地图定义为: Map<Integer,String> map = new HashMap<>(); map.put(2,"ram"); map.put(3,"ram"); map.put(4,"gopal"); map.put(5,"madan"); map.put(6,"shyam"); map.put(7,"gopal"); map.put(8,"ram");我的预期输出是列表,其中仅包含没有重复值的键。56我的方法和思考过程:思考过程1:我将采取map.entrySet().stream().map(....)然后采取映射内的另一个流并过滤存在重复值的值。该方法很快就被浪费了,因为第一个索引值将在嵌套流中再次进行比较,并且我会碰巧过滤掉所有元素。思维过程2我通过以下List方式保持不同的值:List<String> subList = map.entrySet().stream() .map((k)->k.getValue()) .collect(Collectors.toList());进而: map.entrySet().stream() .filter(s -> subList.contains(s.getValue()) ) .map(Map.Entry::getKey) .collect(Collectors.toList());但我得到的输出为2345678输出是显而易见的,因为我从流中选取的值是我在池中比较它的值,其中该值将始终至少出现一次。我再次想到,如果我可以有一个计数器来计数,并且如果该值存在,那么它就会增加,但现在一切似乎都非常模糊。我可以使用流通过索引进行迭代的任何方式,以便我始终可以保留我正在获取的键值并仅与其余值进行比较。希望得到简短的解释。
2 回答
幕布斯6054654
TA贡献1876条经验 获得超7个赞
您可以将任务分为两步。首先计算收集器重复的groupingBy()
值counting()
。
Map<String,Long> valueCount = map.values() .stream() .collect(Collectors.groupingBy(Function.identity(),Collectors.counting()));
其结果是:
{马丹=1,希亚姆=1,戈帕尔=2,拉姆=3}
第二步是仅查找其值不重复的键。因此,为了实现这一点,您可以使用filter()
并按上一步结果过滤地图。
map.entrySet() .stream() .filter(entry -> valueCount.get(entry.getValue())==1).map(Map.Entry::getKey) .collect(Collectors.toList())
小唯快跑啊
TA贡献1863条经验 获得超2个赞
1
您可以在创建时按频率过滤值,subList
例如:
Set<String> uniqueSet = map.values().stream() .collect(Collectors.groupingBy(a -> a, Collectors.counting())) .entrySet().stream() .filter(a -> a.getValue() == 1) .map((Map.Entry::getKey)) .collect(Collectors.toSet());
然后执行与以下相同的操作:
Set<Integer> result = map.entrySet().stream() .filter(e -> uniqueSet.contains(e.getValue())) .map(Map.Entry::getKey) .collect(Collectors.toSet());
或者正如 Holger 在评论中指出的那样,counting
您可以取消一个Boolean
值来过滤唯一值,而不是 :
Set<String> uniqueSet = map.values().stream() .collect(Collectors.toMap(Function.identity(), v -> true, (a,b) -> false)) .entrySet().stream() .filter(Map.Entry::getValue) .map((Map.Entry::getKey)) .collect(Collectors.toSet());
添加回答
举报
0/150
提交
取消