有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java检测流中的重复组

我想确保列表中的所有数字都分组在一起。让我举例说明:

{1, 1, 1, 2, 2}    // OK, two distinct groups
{1, 1, 2, 2, 1, 1} // Bad, two groups with "1"
{1, 2, 3, 4}       // OK, 4 distinct groups of size 1
{1, 1, 1, 1}       // OK, 1 group
{3, 4, 3}          // Bad, two groups with "3"
{99, -99, 99}      // Bad, two groups with "99"
{}                 // OK, no groups

以下是我获取流的方式:

IntStream.of(numbers)
    ...

现在,我需要为“OK”示例传递或返回true,并为“Bad”示例抛出AssertionError或返回false。如何使用流API实现这一点

以下是我当前创建的附加Set解决方案:

Set<Integer> previousNumbers = new HashSet<>();
IntStream.of(numbers)
        .reduce(null, (previousNumber, currentNumber) -> {
                    if (currentNumber == previousNumber) {
                        assertThat(previousNumbers).doesNotContain(currentNumber);
                        previousNumbers.add(currentNumber);
                    }
                    return currentNumber;
                }
        );

共 (1) 个答案

  1. # 1 楼答案

    在我看来,这个问题根本不适合Stream API,但我很好奇如何实现它(不过是以一种性能的方式)

    问题是,你必须跟踪看到的元素,整个测试应该有短路行为。所以我想出了这个解决方案(没有^{):

    public static boolean hasUniqueGroups(int[] arr) {
        Objects.requireNonNull(arr);
        Set<Integer> seen = new HashSet<>();
        for (int i = 0; i < arr.length; i++) {
            if (i == 0 || arr[i] != arr[i - 1]) {
                if (!seen.add(arr[i])) {
                    return false;
                }
            }
        }
        return true;
    }
    

    下一步是引入Stream API,解决方案如下所示:

    public static boolean hasUniqueGroups(int[] arr) {
        Objects.requireNonNull(arr);
        Set<Integer> seen = new HashSet<>();
        return IntStream.range(0, arr.length)
                .filter(i -> i == 0 || arr[i] != arr[i - 1])
                .mapToObj(i -> arr[i])
                .allMatch(seen::add);
    }
    

    注意:为了并行化这个Stream,你应该使用线程安全的Set