如何检查 Java 8 个流中是否存在重复项?
How to check if exists any duplicate in Java 8 Streams?
在 java 8 中,检查列表是否包含重复项的最佳方法是什么?
我的想法是这样的:
list.size() != list.stream().distinct().count()
这是最好的方法吗?
您的代码需要遍历所有元素。如果你想确保没有重复的简单方法,比如
public static <T> boolean areAllUnique(List<T> list){
Set<T> set = new HashSet<>();
for (T t: list){
if (!set.add(t))
return false;
}
return true;
}
会更有效率,因为它可以在找到第一个非唯一元素时立即给你 false
。
这个方法也可以重写为(假设非并行流和线程安全环境)使用 Stream#allMatch
这也是短路的(returns false 立即为第一个元素不' t 满足提供的条件)
public static <T> boolean areAllUnique(List<T> list){
Set<T> set = new HashSet<>();
return list.stream().allMatch(t -> set.add(t));
}
或评论
中提到的@Holger
public static <T> boolean areAllUnique(List<T> list){
return list.stream().allMatch(new HashSet<>()::add);
}
开始这个 class 作为 StreamTool,但我认为必须有更好的方法使用 reduce 或类似的:
public class StreamTool {
/**
* Whether stream records are unique in that stream.
* @param <T> Type of records
* @param records
* @return true if there are no duplicates, false otherwise
*/
public static <T> boolean isUnique(Stream<T> records) {
return records.allMatch(new HashSet<>()::add);
}
}
我使用了以下内容:
1. return list.size() == new HashSet<>(list).size();
.
我不确定它与以下相比如何:
2. return list.size() == list.stream().distinct().count();
和
3.return list.stream().sequential().allMatch(new HashSet<>()::add);
在性能方面。
最后一个 (#3) 不仅可以处理集合(例如列表),还可以处理流(无需显式收集它们)。
更新:最后一个 (#3) 似乎是最好的,不仅因为它可以处理纯流,而且因为它在第一个重复项上停止(而 #1 和 #2 总是迭代到最后) — 正如@Pshemo 在 comment 中所说的那样。
您可以使用计数收集器。
Stream.of(1, 3, 4, 6, 7, 5, 6)
.collect(Collectors.groupingBy(
Function.identity(), Collectors.counting()))
.entrySet().stream().anyMatch(e -> e.getValue() > 1)
给定数组arr,
arr.length != Arrays.stream(arr).distinct().count()
将有助于检查重复项
使用set.add()
速度更快
Set<T> items = new HashSet<>();
list.stream().filter(n -> !items.add(n))
.collect(Collectors.toSet());
在 java 8 中,检查列表是否包含重复项的最佳方法是什么?
我的想法是这样的:
list.size() != list.stream().distinct().count()
这是最好的方法吗?
您的代码需要遍历所有元素。如果你想确保没有重复的简单方法,比如
public static <T> boolean areAllUnique(List<T> list){
Set<T> set = new HashSet<>();
for (T t: list){
if (!set.add(t))
return false;
}
return true;
}
会更有效率,因为它可以在找到第一个非唯一元素时立即给你 false
。
这个方法也可以重写为(假设非并行流和线程安全环境)使用 Stream#allMatch
这也是短路的(returns false 立即为第一个元素不' t 满足提供的条件)
public static <T> boolean areAllUnique(List<T> list){
Set<T> set = new HashSet<>();
return list.stream().allMatch(t -> set.add(t));
}
或评论
中提到的@Holgerpublic static <T> boolean areAllUnique(List<T> list){
return list.stream().allMatch(new HashSet<>()::add);
}
开始这个 class 作为 StreamTool,但我认为必须有更好的方法使用 reduce 或类似的:
public class StreamTool {
/**
* Whether stream records are unique in that stream.
* @param <T> Type of records
* @param records
* @return true if there are no duplicates, false otherwise
*/
public static <T> boolean isUnique(Stream<T> records) {
return records.allMatch(new HashSet<>()::add);
}
}
我使用了以下内容:
1. return list.size() == new HashSet<>(list).size();
.
我不确定它与以下相比如何:
2. return list.size() == list.stream().distinct().count();
和
3.return list.stream().sequential().allMatch(new HashSet<>()::add);
在性能方面。
最后一个 (#3) 不仅可以处理集合(例如列表),还可以处理流(无需显式收集它们)。
更新:最后一个 (#3) 似乎是最好的,不仅因为它可以处理纯流,而且因为它在第一个重复项上停止(而 #1 和 #2 总是迭代到最后) — 正如@Pshemo 在 comment 中所说的那样。
您可以使用计数收集器。
Stream.of(1, 3, 4, 6, 7, 5, 6)
.collect(Collectors.groupingBy(
Function.identity(), Collectors.counting()))
.entrySet().stream().anyMatch(e -> e.getValue() > 1)
给定数组arr,
arr.length != Arrays.stream(arr).distinct().count()
将有助于检查重复项
使用set.add()
速度更快
Set<T> items = new HashSet<>();
list.stream().filter(n -> !items.add(n))
.collect(Collectors.toSet());