如何检查Java 8 Streams中是否存在任何重复?

时间:2022-03-23 06:59:39

In java 8, what's the best way to check if a List contains any duplicate?

在java 8中,检查List是否包含任何重复的最佳方法是什么?

My idea was something like:

我的想法是这样的:

list.size() != list.stream().distinct().count()

Is it the best way?

这是最好的方式吗?

4 个解决方案

#1


30  

Your code would need to iterate over all elements. If you want to make sure that there are no duplicates simple method like

您的代码需要遍历所有元素。如果你想确保没有重复的简单方法,比如

public static <T> boolean containsUnique(List<T> list){
    Set<T> set = new HashSet<>();

    for (T t: list){
        if (!set.add(t))
            return false;
    }

    return true;
}

would be more efficient.

会更有效率。

This method could also be rewritten as (assuming non-parallel streams and thread-safe environment)

此方法也可以重写为(假设非并行流和线程安全的环境)

public static <T> boolean containsUnique(List<T> list){
    Set<T> set = new HashSet<>();
    return list.stream().allMatch(t -> set.add(t));
}

or as @Holger mentioned in comment

或者@Holger在评论中提到

public static <T> boolean containsUnique(List<T> list){
    return list.stream().allMatch(new HashSet<>()::add);
}

#2


7  

I used the following:
1. return list.size() == new HashSet<>(list).size();.

我使用了以下内容:1。return list.size()== new HashSet <>(list).size();.

I'm not sure how it compares to:
2. return list.size() == list.stream().distinct().count();
and
3. return list.stream().sequential().allMatch(new HashSet<>()::add);
in terms of performance.

我不确定它与它的比较:2。return list.size()== list.stream()。distinct()。count(); 3. return list.stream()。sequential()。allMatch(new HashSet <>():: add);在表现方面。

The last one (#3) has possibility to handle not only collections (e.g. lists), but also streams (without explicitly collecting them).

最后一个(#3)不仅可以处理集合(例如列表),还可以处理流(没有明确地收集它们)。

#3


3  

You can use the counting collector.

您可以使用计数收集器。

Stream.of(1, 3, 4, 6, 7, 5, 6)
            .collect(Collectors.groupingBy(
                    Function.identity(), Collectors.counting()))
            .entrySet().stream().anyMatch(e -> e.getValue() > 1)

#4


2  

Started this class as a StreamTool, but I think there must be an even better way with reduce or similar:

以StreamTool开始这个课程,但我认为必须有一个更好的方法来减少或类似:

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


30  

Your code would need to iterate over all elements. If you want to make sure that there are no duplicates simple method like

您的代码需要遍历所有元素。如果你想确保没有重复的简单方法,比如

public static <T> boolean containsUnique(List<T> list){
    Set<T> set = new HashSet<>();

    for (T t: list){
        if (!set.add(t))
            return false;
    }

    return true;
}

would be more efficient.

会更有效率。

This method could also be rewritten as (assuming non-parallel streams and thread-safe environment)

此方法也可以重写为(假设非并行流和线程安全的环境)

public static <T> boolean containsUnique(List<T> list){
    Set<T> set = new HashSet<>();
    return list.stream().allMatch(t -> set.add(t));
}

or as @Holger mentioned in comment

或者@Holger在评论中提到

public static <T> boolean containsUnique(List<T> list){
    return list.stream().allMatch(new HashSet<>()::add);
}

#2


7  

I used the following:
1. return list.size() == new HashSet<>(list).size();.

我使用了以下内容:1。return list.size()== new HashSet <>(list).size();.

I'm not sure how it compares to:
2. return list.size() == list.stream().distinct().count();
and
3. return list.stream().sequential().allMatch(new HashSet<>()::add);
in terms of performance.

我不确定它与它的比较:2。return list.size()== list.stream()。distinct()。count(); 3. return list.stream()。sequential()。allMatch(new HashSet <>():: add);在表现方面。

The last one (#3) has possibility to handle not only collections (e.g. lists), but also streams (without explicitly collecting them).

最后一个(#3)不仅可以处理集合(例如列表),还可以处理流(没有明确地收集它们)。

#3


3  

You can use the counting collector.

您可以使用计数收集器。

Stream.of(1, 3, 4, 6, 7, 5, 6)
            .collect(Collectors.groupingBy(
                    Function.identity(), Collectors.counting()))
            .entrySet().stream().anyMatch(e -> e.getValue() > 1)

#4


2  

Started this class as a StreamTool, but I think there must be an even better way with reduce or similar:

以StreamTool开始这个课程,但我认为必须有一个更好的方法来减少或类似:

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);
    }
}