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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/30053487/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 09:03:01  来源:igfitidea点击:

How to check if exists any duplicate in Java 8 Streams?

javajava-8duplicatesjava-stream

提问by pedrorijo91

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?

这是最好的方法吗?

采纳答案by Pshemo

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 areAllUnique(List<T> list){
    Set<T> set = new HashSet<>();

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

    return true;
}

would be more efficient since it can give you falseimmediately when first non-unique element would be found.

会更有效,因为它可以false在找到第一个非唯一元素时立即为您提供。

This method could also be rewritten as (assuming non-parallel streams and thread-safe environment) using Stream#allMatchwhich also is short-circuit (returns false immediately for first element which doesn't fulfill provided condition)

此方法也可以重写为(假设非并行流和线程安全环境)使用Stream#allMatchwhich 也是短路(对于不满足提供条件的第一个元素立即返回 false)

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

or as @Holgermentioned in comment

或如评论中提到的@Holger

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

回答by geekdenz

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

回答by Sasha

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)不仅可以处理集合(例如列表),还可以处理流(不显式收集它们)。

Upd.: The last one (#3) seems to be the best not only because it can handle pure streams, but also because it stops on the first duplicate (while #1 and #2 always iterate till the end) — as @Pshemo said in comment.

更新:最后一个(#3)似乎是最好的,不仅因为它可以处理纯流,还因为它在第一个重复项上停止(而#1和#2总是迭代到最后)——如@Pshemo在评论中说。

回答by Will Humphreys

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)

回答by Edor Linus

Given array arr,

给定数组 arr,

arr.length!=Arrays.stream(arr).distinct().count()

will help check for duplicates

将有助于检查重复项