比较两个对象的不同属性集

Man*_*oid 5 java compare contains equals

我有一个数据类。字段可以是集合、原语、引用等。我必须检查这个类的两个实例的相等性。通常我们会为此目的重写 equals 方法。但是用例是这样的,要比较的属性可能会有所不同。

所以说,A 类具有以下属性:

int name:
int age:
List<String> hobbies;
Run Code Online (Sandbox Code Playgroud)

在一次调用中,我可能必须根据姓名、年龄检查相等性,而对于另一次调用,我可能必须检查姓名、爱好的相等性。

实现这一目标的最佳实践是什么?

Zab*_*uza 1

anyMatch

您可以通过Stream API解决此问题,使用anyMatch,您的规则基本上定义为Predicates。

例如检查是否有20年龄的人:

List<Person> persons = ...

boolean doesAnyMatch = persons.stream()
    .anyMatch(p -> p.getAge() == 20);
Run Code Online (Sandbox Code Playgroud)

当然,您也可以以与现有项目进行比较的方式设置规则,模仿equals更多:

p -> p.getAge() == otherPerson.getAge()
Run Code Online (Sandbox Code Playgroud)

Predicate

您可以在其他地方设置所有规则,例如Predicates ,然后使用它们。例如:

List<Predicate<Person>> rules = List.of(
    p -> p.getAge() == 20,
    p -> p.getName().equals("John"),
    p -> p.getAge() > 18,
    p -> p.getName().length() > 10 && p.getAge() < 50
);
Run Code Online (Sandbox Code Playgroud)

然后,无论您需要什么,都可以在某种循环中使用它们:

for (Predicate rule : rules) {
    boolean doesAnyMatch = persons.stream()
        .anyMatch(rule);
    ...
}
Run Code Online (Sandbox Code Playgroud)

findAny

您可以替换为和anyMatch的组合来接收实际匹配,即 a ,而不仅仅是 a :filterfindAnyPersonboolean

Person matchingPerson = persons.stream()
    .filter(rule)
    .findAny();
Run Code Online (Sandbox Code Playgroud)