【问题标题】:Remove repeated elements from the Lists inside Map [closed]从地图内的列表中删除重复的元素[关闭]
【发布时间】:2019-08-29 10:20:48
【问题描述】:

假设我有以下地图:

"A": [1, 2, 3, 4]
"B": [5, 6, 1, 7]
"C": [8, 1, 5, 9]

如何从数组中删除重复的元素,以便返回只包含从未重复的元素的地图?

"A": [2, 3, 4]
"B": [6, 7]
"C": [8, 9]

【问题讨论】:

  • 请展示您为更接近解决方案而编写的内容。
  • 遍历所有值,不管它们属于哪个键,计算每个值的数量(你可以使用 Map )。现在您知道应该删除哪个字符了。
  • 这是家庭作业吗?
  • 这不是家庭作业。我需要创建一个方法来接收像上面一样的 HashMap,我需要删除重复列表中的 itens,我无法解决这个问题。

标签: java list java-8 hashmap


【解决方案1】:

你可能想这样做:

// Initializing the map
Map<String, List<Integer>> map = new LinkedHashMap<String, List<Integer>>() {
    {
        put("A", new ArrayList<>(Arrays.asList(1, 2, 3, 4)));
        put("B", new ArrayList<>(Arrays.asList(5, 6, 1, 7)));
        put("C", new ArrayList<>(Arrays.asList(8, 1, 5, 9)));
    }
};

// finding the common elements
List<Integer> allElements = map.values().stream().flatMap(List::stream).collect(Collectors.toList());
Set<Integer> allDistinctElements = new HashSet<>();
Set<Integer> commonElements = new HashSet<>();
allElements.forEach(element -> {
    if(!allDistinctElements.add(element)) {
        commonElements.add(element);
    }
});

// removing the common elements
map.forEach((key, list) -> list.removeAll(commonElements));

// printing the map
map.forEach((key, list) -> System.out.println(key + " = " + list));

输出:

A = [2, 3, 4]
B = [6, 7]
C = [8, 9]

【讨论】:

  • 数字5也应该去掉。
  • @LucianoBorges 哎呀,我以为你想删除所有列表中常见的元素。现在我已经更新了代码。请检查。
  • 使用带有副作用的forEach 是个坏主意 - 请阅读this
  • @Adrian 我认为这与访问static Map 有关,该static MapparallelStream 中用于多个线程(并行)时共享。我认为我的代码中不会有这样的问题。
【解决方案2】:

首先你必须计算每个列表中的数字

Map<Integer, Long> countMap = map.values().stream()
            .flatMap(List::stream)
            .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));

然后在 count == 1 的地方过滤

Map<String, List<Integer>> result = map.entrySet().stream()
            .collect(Collectors.toMap(Map.Entry::getKey, e -> e.getValue().stream()
                    .filter(i -> countMap.get(i) == 1).collect(Collectors.toList())));

【讨论】:

  • @LucianoBorges 这个解决方案稍微好一点,因为我只使用了一张额外的地图,而且我只进行了 2 次迭代
  • 而地图中的数组是一个对象数组,这个标识函数应该起作用吗?因为,就我而言,它不起作用。是否需要在对象上创建equals方法?
  • @LucianoBorges 如果该对象将成为地图的键,那么是的,您需要 equals 和 hashCode。或者,如果您的对象有例如唯一 ID,您可以用例如替换身份功能o -&gt; o.getId()
猜你喜欢
  • 2014-12-17
  • 1970-01-01
  • 1970-01-01
  • 2018-01-01
  • 2020-05-27
  • 1970-01-01
  • 2015-01-05
  • 2012-05-09
  • 1970-01-01
相关资源
最近更新 更多