java - 如果列表中出现多次,则删除该项目的所有实例
问题描述
给定一个数字列表:{ 4, 5, 7, 3, 5, 4, 2, 4 }
所需的输出将是:{ 7, 3, 2 }
我正在考虑的解决方案是在给定列表的 HashMap 下方创建:
Map<Integer, Integer> numbersCountMap = new HashMap();
其中 key 是列表中的值,value 是出现次数。
然后循环遍历 HashMap 条目集,如果数字包含大于 1 的计数,则从列表中删除该数字。
for (Map.Entry<Int, Int> numberCountEntry : numbersCountMap.entrySet()) {
if(numberCountEntry.getValue() > 1) {
testList.remove(numberCountEntry.getKey());
}
}
我不确定这是否是解决此问题的有效方法,因为remove(Integer)
对列表的操作可能很昂贵。我也在创建额外的地图数据结构。并循环两次,一次在原始列表上创建地图,然后在地图上删除重复项。
能否请您提出一个更好的方法。可能是 Java 8 有更好的实现方式。我们也可以使用 Java 8 中的 Streams 和其他新结构在几行代码中完成它吗?
解决方案
通过流,您可以使用:
Map<Integer, Long> grouping = integers.stream()
.collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
grouping.values().removeIf(c -> c > 1);
Set<Integer> result = grouping.keySet();
或者正如@Holger 提到的那样,您只想知道列表中是否有多个整数,所以只需执行以下操作:
Map<Integer, Boolean> grouping = integers.stream()
.collect(Collectors.toMap(Function.identity(),
x -> false, (a, b) -> true,
HashMap::new));
grouping.values().removeIf(b -> b);
// or
grouping.values().removeAll(Collections.singleton(true));
Set<Integer> result = grouping.keySet();
推荐阅读
- java - 在for循环中找到最大值
- swift - NStimer 和 Dispatchqueue 在使用 airpot 时启动有点晚
- javascript - 在 handleChange Typescript 中传递值
- ios - flutter iOS有白屏
- javascript - 将风向从度数转换为文本
- javascript - content.js 在同一页面的不同框架上的所有单独执行如何相互通信?
- amazon-web-services - Glue Crawler 无法识别时间戳
- javascript - 在 gatsby 构建之前运行 python 脚本
- r - 用新值向量替换列的唯一值
- python - 使用 PIL 调整大小的正确方法来替换 scipy.misc.imresize