java之简化java流以查找重复属性

虾米哥 阅读:29 2025-01-19 22:14:33 评论:0

我有一个 users list 并且我想找到所有具有重复名称的用户:

var allNames = users 
              .stream() 
              .map(u -> u.getName()).collect(Collectors.toList()); 
 
var duplicateNames = allNames 
                .stream() 
                .filter(i -> Collections.frequency(allNames, i) > 1) 
                .collect(Collectors.toSet()); 

我可以改进/简化上述解决方案吗?

例如,实际上我创建了一个包含所有名称的列表,然后对其进行过滤。如何遍历列表以查找其重复名称而不创建附加列表 allNames ?

请您参考如下方法:

一种解决方案是

var duplicate = users.stream() 
    .collect(Collectors.toMap(User::getName, u -> false, (x,y) -> true)) 
    .entrySet().stream() 
    .filter(Map.Entry::getValue) 
    .map(Map.Entry::getKey) 
    .collect(Collectors.toSet()); 

这将创建一个中间 Map<String,Boolean>记录哪个名称出现多次。您可以使用 keySet()该 map 而不是收集到一个新的 Set :
var duplicate = users.stream() 
    .collect(Collectors.collectingAndThen( 
        Collectors.toMap(User::getName, u -> false, (x,y) -> true, HashMap::new), 
            m -> { 
                m.values().removeIf(dup -> !dup); 
                return m.keySet(); 
            })); 

循环解决方案可以简单得多:
HashSet<String> seen = new HashSet<>(), duplicate = new HashSet<>(); 
for(User u: users) 
    if(!seen.add(u.getName())) duplicate.add(u.getName()); 


标签:java
声明

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

关注我们

一个IT知识分享的公众号