有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java如何修改/删除HashMap中的两个ArrayList元素?

描述

我有一个HashMap<ArrayLists<Integer>, <Integer>>,类似于以下({Key=Value}):

{[1]=1, [3]=1, [1, 4, 6]=1, [0, 2, 3, 5, 6]=3, [6]=1}

我需要比较然后修改/删除不同ArrayLists中的元素(即HashMap中的元素),直到满足以下条件:

  1. 每个ArrayList元素只属于一个列表,该列表具有最高的Value
  2. 如果Value = 1用于包含该元素的所有列表,则ArrayList元素属于单例列表
  3. 如果ArrayList变为空,则应将其从HashMap中删除

因此,对于上面的示例,应该以以下内容结束:

{[1]=1, [4]=1, [0, 2, 3, 5, 6]=3}

我习惯于使用数组来做这样的事情。这一次,拥有HashMapArrayList的特性是可行的,但我目前不习惯对这些数据类型进行更复杂的修改。我做了几次尝试,并不得不防止ConcurrentModificationExceptionIllegalStateException,但尚未完全成功。我也有一种感觉,我的实现变得不必要的复杂,所以我非常希望看到有经验的人实现这样的东西


关于HashMap的注记

我使用HashMap(可以随意提出更合适的建议)的原因是Value是指ArrayList被“遇到”并添加到HashMap的次数


最小示例

我最近一次不工作(IndexOutOfBoundsException)尝试的最小示例。注意HashMapArrayList的创建在这里是静态完成的,因为在我的实际程序中,它是基于文件内容非确定性地完成的

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class Test {
    public static void main(String[] args) {
        Map<List<Integer>, Integer> example = new HashMap<>(7);
        List<Integer> list = new ArrayList<>(7);
        list.add(1);
        example.put(list, 1);
        list = new ArrayList<>(7);
        list.add(3);
        example.put(list, 1);
        list = new ArrayList<>(7);
        list.add(1);
        list.add(4);
        list.add(6);
        example.put(list, 1);
        list = new ArrayList<>(7);
        list.add(0);
        list.add(2);
        list.add(3);
        list.add(5);
        list.add(6);
        example.put(list, 3);
        list = new ArrayList<>(7);
        list.add(6);
        example.put(list, 1);
        System.err.println(example);

        Map<List<Integer>, Integer> copy = new HashMap<>(example);
        for (Map.Entry<List<Integer>, Integer> outer : example.entrySet()) {
            for (Map.Entry<List<Integer>, Integer> inner : copy
                .entrySet()) {
                for (int i : outer.getKey()) {
                    int oSize = outer.getKey().size();
                    int iSize = inner.getKey().size();
                    int oValue = outer.getValue();
                    int iValue = inner.getValue();

                    if (!(inner.equals(outer)) && (inner.getKey()
                        .contains(i))) {
                        if (oSize == 1) {
                            if (oValue < iValue) {
                                outer.getKey().remove(i);
                            } else {
                                inner.getKey().remove(i);
                            }
                        } else if (iSize == 1) {
                            if (iValue < oValue) {
                                outer.getKey().remove(i);
                            } else {
                                inner.getKey().remove(i);
                            }
                        } else {
                            if (oValue < iValue) {
                                outer.getKey().remove(i);
                            } else {
                                inner.getKey().remove(i);
                            }
                        }
                    }
                }
            }
        }
    }
}

共 (2) 个答案

  1. # 1 楼答案

    在我看来很糟糕,我建议在第一轮中订购map值(根据最高值),然后用业务逻辑完成我们的删除工作

    例如:

            Map<List<Integer>, Integer> example = new HashMap<>();
            // data initialize
    
            // order by Map.Entry::getValue desc
            List<Map.Entry<List<Integer>, Integer>> collect = example.entrySet()
                    .stream()
                    .sorted((e1, e2) -> e2.getValue() - e1.getValue())
                    .collect(Collectors.toList());
    
            // remove duplicate list element in Map.Entry::getKey
            Set<Integer> tmp = new HashSet<>();
            // collect.forEach(c -> c.getKey().removeIf(next -> !tmp.add(next)));
            example = collect
                    .stream()
                    .filter(c -> {
                        c.getKey().removeIf(next -> !tmp.add(next));
                        return !c.getKey().isEmpty();
                    })
                    .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
    
  2. # 2 楼答案

    使用ArrayList作为HashMap(Are mutable hashmap keys a dangerous practice?)的键是非常不寻常的。 但假设您对此没有问题,要更新映射条目,您可以从hasmap中删除该条目(列表和整数),创建一个包含您所做更改的新列表,然后在必要时重新插入