我有List<Person> persons = new ArrayList<>();
,我想列出所有唯一名称。我的意思是,如果有&#34; John&#34;,&#34; Max&#34;,&#34; John&#34;,&#34; Greg&#34;那么我只想列出&#34; Max&#34;和#34; Greg&#34;。有没有办法用Java流做到这一点?
答案 0 :(得分:8)
我们可以使用流和Collectors.groupingBy
来计算每个名称的出现次数 - 然后过滤出现多次出现的任何名称:
List<String> res = persons.stream()
.collect(Collectors.groupingBy(Function.identity(), Collectors.counting()))
.entrySet()
.stream()
.filter(e -> e.getValue() == 1)
.map(e -> e.getKey())
.collect(Collectors.toList());
System.out.println(res); // [Max, Greg]
答案 1 :(得分:4)
首先猜测解决方案。
persons.stream()
.collect(Collectors.groupingBy(Function.identity(), Collectors.counting()))
.entrySet()
.stream()
.filter(entry -> entry.getValue() == 1)
.map(Map.Entry::getKey)
.collect(Collectors.toList())
答案 2 :(得分:2)
List persons = new ArrayList();
persons.add("Max");
persons.add("John");
persons.add("John");
persons.add("Greg");
persons.stream()
.filter(person -> Collections.frequency(persons, person) == 1)
.collect(Collectors.toList());
答案 3 :(得分:1)
这应该删除所有重复的元素。
List<String> persons = new ArrayList<>();
persons.add("John");
persons.add("John");
persons.add("MAX");
persons.add("Greg");
Set<String> set = new HashSet<String>();
Set<String> duplicateSet = new HashSet<String>();
for (String p : persons) {
if (!set.add(p)) {
duplicateSet.add(p);
}
}
System.out.println(duplicateSet.toString());
set.removeAll(duplicateSet);
System.out.println(set.toString());
答案 4 :(得分:1)
您可以使用Collections.frequency
检查列表中的元素出现情况,如下所示,以过滤重复项:
List<String> listInputs = new ArrayList<>();
//add your users
List<String> listOutputs = new ArrayList<>();
for(String value : listInputs) {
if(Collections.frequency(listInputs, value) ==1) {
listOutputs.add(value);
}
}
System.out.println(listOutputs);
答案 5 :(得分:0)
这是一篇旧帖子,但我想提出另一种基于自定义收集器的方法:
public static <T> Collector<T, ?, List<T>> excludingDuplicates() {
return Collector.<T, Map<T, Boolean>, List<T>>of(
LinkedHashMap::new,
(map, elem) -> map.compute(elem, (k, v) -> v == null),
(left, right) -> {
right.forEach((k, v) -> left.merge(k, v, (o, n) -> false));
return left;
},
m -> m.keySet().stream().filter(m::get).collect(Collectors.toList()));
}
这里我使用Collector.of
来创建一个自定义收集器,它将在LinkedHashMap
上累积元素:如果该元素不作为键存在,则其值为true
,否则它将是false
。合并函数仅应用于并行流,并通过尝试将right
映射的每个条目放在left
映射中,将right
映射合并到left
映射中,将已存在的键的值更改为false
。最后,finisher函数返回一个列表,其中包含值为true
的地图键。
此方法可按如下方式使用:
List<String> people = Arrays.asList("John", "Max", "John", "Greg");
List<String> result = people.stream().collect(excludingDuplicates());
System.out.println(result); // [Max, Greg]
这是另一种比使用自定义收集器更简单的方法:
Map<String, Boolean> duplicates = new LinkedHashMap<>();
people.forEach(elem -> duplicates.compute(elem, (k, v) -> v != null));
duplicates.values().removeIf(v -> v);
Set<String> allUnique = duplicates.keySet();
System.out.println(allUnique); // [Max, Greg]
答案 6 :(得分:0)
您可以尝试以下代码。
List<Person> uniquePersons = personList.stream()
.collect(Collectors.groupingBy(person -> person.getName()))
.entrySet().stream().filter(stringListEntry -> stringListEntry.getValue().size()==1)
.map(stringListEntry -> { return stringListEntry.getValue().get(0); })
.collect(Collectors.toList());
答案 7 :(得分:0)
这是我的解决方案:
List<String> persons = new ArrayList<>();
persons.add("John");
persons.add("John");
persons.add("MAX");
persons.add("Greg");
persons.stream()
.distinct()
.sorted()
.collect(Collectors.toList());