首页 > 解决方案 > Java11中的谓词过滤所有元素

问题描述

我打算使用 Java11。学习一种新方法Predicate.not,我发现我当前的代码只能找到 cat family:

List<String> animals = List.of("cat", "leopard", "dog", "lion", "horse");
Predicate<String> cats = a -> !a.equals("dog") && !a.equals("horse");
Set<String> filterCat = animals.stream().filter(cats).collect(Collectors.toSet());
System.out.println(filterCat);

输出是:

豹,猫,狮子

现在我正在尝试使用新方法并且输出不正确。我该如何纠正?我做错什么了?

我后来的代码:

Predicate<String> updatedCatFilter = Predicate.not(a -> a.equals("dog") && a.equals("horse"));
Set<String> catFamily = animals.stream().filter(updatedCatFilter).collect(Collectors.toSet());
System.out.println(filterCat);

但这现在输出了我所有的列表。

马, 豹, 猫, 狗, 狮子

标签: javapredicatejava-11functional-interface

解决方案


我做错什么了?

您似乎缺少基本的德摩根定律,该定律指出

!(a || b) == !a && !b

!(a && b) == !a || !b

我该如何纠正?

所以你应该改变你的代码来使用

Predicate.not(a -> a.equals("dog") || a.equals("horse")); // !(a || b)

这应等同于您现有的代码

Predicate<String> cats = a -> !a.equals("dog") && !a.equals("horse");

也可以看作:

Predicate<String> notDog = a -> !a.equals("dog");
Predicate<String> notHorse =  a -> !a.equals("horse");
Predicate<String> cats = notDog.and(notHorse); // !a && !b

推荐阅读