如何比较两个对象,每个对象都包含Java中的原始类型和对象集合?

pra*_*net 4 java java-8

我有两个如下的DTO对象,请注意,我在使用lombok来避免样板代码。

贸易协定

import lombok.Data;
import java.util.List;

@Data
public class DtoA {

    private String name;
    private String number;
    private List<String> aList;
}
Run Code Online (Sandbox Code Playgroud)

企业对企业

import lombok.Data;
import java.util.List;

@Data
public class DtoB {
    private String name;
    private String phone;
    private List<String> bList;
}
Run Code Online (Sandbox Code Playgroud)

我想比较两个对象的特定字段,所以我创建了一个适配器类型的对象,如下所示

DtoAdapter

import lombok.Data;
import java.util.List;

@Data
public class DtoAdapter {
    private String nameText;
    private List<String> xList;
}
Run Code Online (Sandbox Code Playgroud)

以下是我尝试进行比较的主要方法的Test类,由于aList和bList包含不同顺序的字符串,因此此比较失败。我想比较列表的内容而不必担心它们的顺序。

测试

import junit.framework.Assert;
import java.util.ArrayList;
import java.util.List;

public class Test {
    public static void main(String[] args) {
        DtoA a = new DtoA();
        List<String> aList = new ArrayList<>();
        aList.add("x"); aList.add("y"); aList.add("z");
        a.setName("abc"); a.setNumber("123"); a.setAList(aList);

        DtoB b = new DtoB();
        List<String> bList = new ArrayList<>();
        bList.add("z"); bList.add("x"); bList.add("y");
        b.setName("abc"); b.setPhone("123"); b.setBList(bList);

        DtoAdapter a1 = new DtoAdapter();
        a1.setNameText(a.getName()); a1.setXList(a.getAList());

        DtoAdapter b1 = new DtoAdapter();
        b1.setNameText(b.getName()); b1.setXList(b.getBList());

        // comparision failing because of lists contains string in different orders
        Assert.assertEquals(a1, b1);
    }
}
Run Code Online (Sandbox Code Playgroud)

注意:我已经尝试编写compareTo(通过在DtoAdapter类中实现可比较的接口),但是我无法使用compareTo方法编写两个列表的比较,如下所示

具有可比接口的DtoAdapter

import lombok.Data;
import java.util.List;

@Data
public class DtoAdapter implements Comparable<DtoAdapter>{
    private String nameText;
    private List<String> xList;

    @Override
    public int compareTo(DtoAdapter o) {
        return this.getNameText().compareTo(o.getNameText());
        // how to compare this.getXList() and o.getXList() with compareTo?
    }
}
Run Code Online (Sandbox Code Playgroud)

Nam*_*man 6

您期待的不是扩展类Comparable的重写equals实现(hashcode当然还有)。

@Override
public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;
    DtoAdapter that = (DtoAdapter) o;
    // following line of code specifically
    return Objects.equals(nameText, that.nameText) &&
            that.getXList().containsAll(xList) && xList.containsAll(that.getXList());
}
Run Code Online (Sandbox Code Playgroud)

除了的文档Comparable,该接口主要用于元素排序而不是相等比较:

该接口对实现该接口的每个类的对象强加了总体排序。该排序称为类的自然排序,而该类的compareTo方法称为其自然比较方法

  • 加一; 但是有两件事:1)如果实现`Comparable`,强烈建议您重写equals / hashCode 2)我希望有时会有一个接口`EqualsAndHashCode` ...我有时只想在方法中使用这些类型,并且我希望我可以说`List &lt;?扩展EqualsAndHashCode&gt;`.... (2认同)