如何在Java 8中比较两个对象

3

举个例子,假设你有两个员工对象,其值相同,如下所示。

Employee employee1 = new Employee(1001, "Sam", 20000);
Employee employee2 = new Employee(1001, "Sam", 20000);
if(doCompareEmployees(employee1, employee2)){
    System.out.println("Both employee objects are same.");
}else{
    System.out.println("Both employee objects are not same.");
}

//Here is compare method using java 8.

private boolean doCompareEmployees(Employee employee1, Employee employee2) {
int returnValue = Comparator.comparing(Employee::getID)
    .thenComparing(Employee::getName)
    .thenComparing(Employee::getSalary)
    .compare(employee1, employee2);
    if (returnValue != 0){
        return false;
    }   
    return true;
}

我想了解一下,在Java 8中是否有其他更好的方法来比较对象?


4
除非您想要基于特定字段进行自定义比较,否则首选方法是在您的Employee类中覆盖equals(并使hashcode保持一致),并将此“doCompareEmployees”方法替换为“employee1.equals(employee2)”。 - Alexis C.
2
标准选项仍然是向 Employee 添加一个适当的 equals 方法。如果不可能,那么基于属性的检查的最佳方法也没有改变:return employee1.getID()==employee2.getID()) && employee1.getName().equals(employee2.getName()) && employee1.getSalary()==employee2.getSalary()); - Holger
1
可能是 https://dev59.com/tXRB5IYBdhLWcg3w6LR2 的重复问题。 - tkruse
有很多可能的方法。默认情况下实现 Comparable 接口的某些类具有预先构建的“自然顺序”,可以使用它,或者如果您需要特定的排序方式,则可以使用 Comparator 接口并定义自己的排序方法。 - whatamidoingwithmylife
2个回答

4
如果您不想在对象上定义排序,通常不需要编写 Comparator。
为一个类定义相等性的典型方法是定义 equals()hashCode() 方法。为了实现 hashCode(),可以使用 Objects.hash()(自 Java 7 起提供)来帮助。
public int hashCode() {
    return Objects.hash(id, name, salary);
}

public boolean equals(Object o) {
    if (o == this) return true;
    if (o == null || o.getClass() != getClass()) return false;
    Employee e = (Employee) o;
    return id == e.id && salary == e.salary && Objects.equals(name, e.name);
}

虽然Lambda表达式在某些情况下可以编写非常优美的代码,但它们并不是每个问题的最佳解决方案。


1
直到现在我才知道Objects.hash(),这太棒了 :-) - André Stannek

1
你可以检查这个LambdaEquals实用程序。然而,作为一个好习惯,你应该坚持重写equals以获得最佳性能。重写"equals"方法可能比Comparator.comparing更快。
下面是Hoopje提供的相同覆盖示例,只是略有不同。
在Employee类中重写equals方法:
public class Employee {
.....
.....
@Override
public boolean equals(Object o) {
     if(super.equals(o)) {
         return true;
     }
    if(!(o instanceof Employee)) {
        return false
    }

    Employee otherEmployee = (Employee) o;

    return 
        id == otherEmplyee.getId &&
        name == otherEmplyee.getName() &&
        salary == otherEmplyee.getSalary;

}


//Use the equal method
if(emp1.equals(emp2) {
    //do something
}

super.equals(0)??? - ZhekaKozlov
@ZhekaKozlov 不好意思,我弄错了。打错字了 :) - Octtavius
我会将其更改为 this == o - ZhekaKozlov
== 比较的是引用,而不是值。你会得到错误的结果。 - Octtavius
1
在这种情况下,super.equals(o)this == o是等价的,因为Employee的直接超类是Object,而Object.equals()是基于==实现的。然而,通常情况下,您不希望以您所做的方式调用super.equals(o)。假设EmployeeA的子类并继承了它的salary字段。那么new Employee(1, "John", 10).equals(new Employee(2, "Mark", 10)) == true,因为两者都有相同的薪水,因此A.equals(o)将返回true。 - Hoopje

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接