CodeGym /Java 博客 /China /Java 谓词及示例
作者
Artem Divertitto
Senior Android Developer at United Tech

Java 谓词及示例

已在 China 群组中发布
一般来说,谓词是指确定一个值是 true 还是 false 的语句。在编程中,谓词意味着带有一个返回 boolean 值的参数的函数。 函数接口谓词在 Java 8 中实现。“函数”意味着它只包含一个抽象方法。它接受参数并返回 boolean。 在 Java 中,函数接口用于处理 Lambda 表达式、构造方法和方法引用。 通常 Java 8 谓词用于为对象集合应用过滤器。我们了解下其主要应用和广泛使用的方法,并解决一些实践问题。

为什么开发人员使用谓词

基本上,开发人员可以将谓词用于任何涉及根据预定义的标准对项目求值并返回 boolean 值的任务。 下面是开发人员使用谓词处理的简单任务的示例:
  • 过滤一组整数。
  • 通过确保数据符合几个预定义的条件来对列表进行排序(例如,通过设置价格和重量条件来组织一系列项目)。
  • 在并发编程中使用实用程序包。
谓词是软件测试中的一个重要特征。函数接口使得分离测试单元变得更加容易,提高了应用程序代码的可读性和可管理性。

Java 中的谓词语法

Java 8 中引入了 java.util.function.Predicate 作为 Lambda 中处理评估印象的替代方法。接口的标准视图是 Predicate<T>,其中 T 是返回 boolean 值的单个参数。 Java 谓词包含一个函数(抽象)方法 test(Object),它在给定的对象上对这个谓词求值。

@FunctionalInterface
public interface Predicate<T> {
boolean test(T t);
}
下面是一个编写简单谓词的示例,该谓词根据“大于”和“小于”条件过滤整数。

// An example of a simple Java predicate
  
import java.util.function.Predicate; 
public class PredicateExample { 
    public static void main(String[] args) 
    { 
        // Creating predicate 
        Predicate<Integer> lesserThan = i -> (i < 18);  
  
        // Calling Predicate method 
        System.out.println(lesserThan.test(10));  
    }
}
输出将为 true,因为 10 < 18。 filter() 中谓词的另一个例子。谓词有助于从年龄列表中过滤所有成年人。

  import java.util.List;
  import java.util.function.Predicate;

  public class PredicateExample {
      public static void main(String[] args) {
          List<Integer> ages = List.of(17, 18, 19, 28, 18, 28, 46, 7, 8, 9, 21, 12);
          NotLessThan18<Integer> isAdult = new NotLessThan18<>();
          ages.stream().filter(isAdult).forEach(System.out::println);
      }
  }



class NotLessThan18<E> implements Predicate<Integer> {

      @Override
      public boolean test(Integer v) {
          Integer ADULT = 18;
          return v >= ADULT;
      }
  }
输出是:
18 19 28 18 28 46 21

Java 8 Predicate 方法

Predicate 接口包含一些方法。
  • boolean test(T t) 计算给定参数上的谓词的值。
  • default Predicate<T> and(Predicate<? super T> other) 返回一个谓词,该谓词表示该谓词与另一个谓词的短路逻辑与。
  • default Predicate<T> or 返回一个组合谓词,表示此谓词与另一个谓词的短路逻辑或。
  • default Predicate<T> negate() 返回一个逻辑上与该谓词相反的谓词。
  • 如果两个参数根据 Objects.equals(Object, Object) 相等,则 default Predicate<T> isEqual(Object targetRef) 返回测试结果。

boolean test(T t)

这是一个用于 Java 谓词的函数方法,它评估给定的参数是否满足谓词的条件。

示例:这里我们为每个 18 岁或以上的人创建一个 adult 谓词。test() 方法获取一个整数值并进行检查。


import java.util.function.Predicate;
public class PredicateTestTest {
   public static void main(String[] args) {
       Predicate<Integer> adult = i -> i >= 18;
       System.out.println(adult.test(12));
       System.out.println(adult.test(19));
       System.out.println(adult.test(21));
   }
}
上面代码的输出会是什么?在第一种情况下,由于 12 小于 18,所以它将为 false。对于第二个和第三个场景,条件得到满足,因此返回将为 true。
false true true

default Predicate.and()

此方法表示“与”运算符。如果一个给定的谓词不符合设定的条件,另一个将不会得到求值,这就是原因。 示例:让我们在 Java 中编写谓词,使用 and() 过滤所有已经成年但小于 65 岁的人。我们使用 predicate.add () 并使用 lambda 为这些条件编写 java 谓词:如果条件为真,则该应用程序返回下列语句:

import java.util.function.Predicate;

   public class PredicateDemo {
       public static void main(String[] args) {
           Predicate<Integer> adultYet = i -> i >= 18;
           Predicate<Integer> adultStill = i -> i < 65;
           System.out.println(adultYet.and(adultStill).test(5));
           System.out.println(adultYet.and(adultStill).test(38));
           System.out.println(adultYet.and(adultStill).test(90));
       }
   }
输出是:
false true false

default Predicate.or()

Predicate.or() 方法表示“或”运算符。这意味着即使两个谓词中的一个为 true,另一个为 false,条件也将保持为 true。 示例:现在对字符串求值。尝试使用 OR 方法对包含子字符串“my”或“crayon”的所有短语进行排序。

import java.util.function.Predicate;

  public class PredicateDemo2 {
      public static void main(String[] args) {
          Predicate<String> containsA = t -> t.contains("crayon");
          Predicate<String> containsB = t -> t.contains("my");
          System.out.println(containsA.or(containsB).test("here is my crayon"));
          System.out.println(containsA.or(containsB).test("here is my pencil"));
          System.out.println(containsA.or(containsB).test("here is John's crayon"));
          System.out.println(containsA.or(containsB).test("here is John's pencil"));
      }
  }
输出是:
true true true false

default Predicate negate()

negate() 方法用于收集所有不符合预定义标准的值。 示例:如果你想对类“Tomatoes”进行排序并找到所有不是“Red”的条目,你可以编写一个谓词并快速浏览整个序列。试着自己编写代码,并在完成后对照解决方案进行检查。

import java.util.function.Predicate;

public class PredicateDemo3 {
public static void main(String[] args) {
 Predicate<Integer> adult = i -> i >= 18;
System.out.println(adult.negate().test(7));  System.out.println(adult.negate().test(19))
  }
   }
输出是:
true false

static Predicate isEqual(Object targetRef)

如果要确定两个对象是否等于定义为 Objects.equals() 参数的值,此方法非常有用。如果你需要比较相似的测试结果,这种方法尤其有用。 例如:假设你要比较两个车梨,并想确定是否两者所含的水果都有标准的重量和颜色。在这种情况下,静态谓词 isEqual(Object targetRef) 正是你需要的方法。 我们看看 isEqual 如何检查两个字符串是否相等:

import java.util.function.Predicate;

public class PredicateDemo2 {
   public static void main(String[] args) {
       Predicate<String> i = Predicate.isEqual("here is my crayon");
       System.out.println(i.test("here is my pencil"));
       System.out.println(i.test("here is my crayon"));
   }
}
如果你要分析的对象符合标准条件,该函数将返回 true。输出是:
false true

Java IntPredicate

Java IntPredicate 是一个函数接口,因此可以将其用作 lambda 表达式或方法引用的赋值目标。IntPredicate 对整数进行运算,并根据条件返回谓词值。 如谓词接口,IntPredicate 还包含 test()and()negate()or() 方法。 下面是 IntPredicate 的示例。它还从数组中过滤掉所有成年人(18 岁或以上)。

import java.util.Arrays;
import java.util.function.IntPredicate;

public class IntPredicateExample {

   public static void main(String[] args) {

       int[] ages = { 18, 28, 18, 46, 90, 45, 2, 3, 1, 5, 7, 21, 12 };

       IntPredicate p = n -> n >= 18;

       Arrays.stream(ages).filter(p).forEach(System.out::println);
   }
}
输出是:
18 28 18 46 90 45 21
Java 谓词及示例 - 1

使用 Java 编写明确的谓词

Java 谓词功能强大,使用起来很有趣。然而,除非你注意到你编写的 lambda 表达式是如何影响代码的,否则就有可能因为混乱的谓词而降低代码的可维护性。 下面是一些简单的实践,可以帮助你确保函数接口易于管理和阅读。

  • 不要重复自己 — 不要使用 Java 编写具有重复的值、方法和条件的谓词。这样,你浪费了生产时间,并使代码混乱。
  • 将谓词与应用代码分开,以确保可测试性。除此之外,创建一个谓词单元测试计划并坚持下去。
  • 使用导入和组合模式来确保你的类不会臃肿,并且易于管理。
  • 考虑将 Java 谓词移动到 Helper 类 — 这样,你可以提高代码的可重用性并简化维护。
  • 可读性 — 尽可能使用单行语句而不是复杂谓词。炫耀你对复杂功能接口的理解可让你显得胜出一筹。不过,说到维护,少即是多。
评论 (1)
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION
Brandon Turner 级别 1,Hartsville south Hartselle Okīsowa TkciōCityPopÇ_íñ5ø,United States
24 十一月 2022
So professional in ADT Jova5 way system base stroer format. Meta would love to picking up on uses my opinion. Kou-no Li 78 Hjiu-ai kuuuirno for new ones.