查找流的哪个元素与allmatch中的给定谓词不匹配

san*_*kum 6 java java-8 java-stream

我想知道哪个元素在谓词中失败了allmatch.

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
boolean isEven = numbers.stream().allMatch(n-> n % 2 == 0);
Run Code Online (Sandbox Code Playgroud)

isEvenfalse因为元素1未通过谓词.

我可以使用forEach流来查找哪个元素失败:

numbers.stream().forEach(n -> {
            if (n % 2 != 0)
                System.out.println(n + "is Odd");
        });
Run Code Online (Sandbox Code Playgroud)

有没有办法找出哪些元素在allmatch返回时失败了谓词false

Mis*_*sha 6

请记住,这allMatch是一个短路操作,这意味着流API可能会返回false而不会找到所有未通过测试的元素.

因此,如果您想要找到所有失败的元素,您可能需要做更多的工作而不是简单allMatch(如其他答案所示).但是,如果您只想找到一个未通过测试的元素,请使用findAny以下命令:

Optional<Integer> odd = numbers.stream()
    .filter(n -> n % 2 != 0)
    .findAny();

boolean isEven = !odd.isPresent();

odd.ifPresent(x -> System.out.println(x + " is odd"));
Run Code Online (Sandbox Code Playgroud)


Eug*_*ene 5

对于这个例子:

Map<Boolean, List<Integer>> map = numbers.stream()
            .collect(Collectors.partitioningBy(x -> x % 2 == 0));

    System.out.println(map); // {false=[1, 3, 5], true=[2, 4]}
Run Code Online (Sandbox Code Playgroud)

你也可以简单地记录它,例如:

boolean isEven = numbers.stream().allMatch(n -> {
        boolean test = n % 2 == 0;
        if (!test) {
            System.out.println("Failed = " + n);
        }
        return test;
    });
Run Code Online (Sandbox Code Playgroud)

但如果你运行它,这可能会引入有趣的结果parallel.输出是不可预测的.那isEven仍然会返回正确的结果,但你看到的Syso是完全无法预测的.可能 :

 Failed = 3
 Failed = 1
 Failed = 5
Run Code Online (Sandbox Code Playgroud)

另一方面可能是:

 Failed = 3
Run Code Online (Sandbox Code Playgroud)

  • @sanchitkum这个`numbers.stream().filter(n - >!(n%2 == 0)).findAny()`返回一个`Optional`,它可能包含失败的值(如果它是非空的) .但请注意,`findAny`和`findFirst`是不同的东西,如果流是并行的,可能会返回不同的值,你需要知道你真正想要的那个. (2认同)