当前位置: 首页 > 知识库问答 >
问题:

如何比较java中两个各包含原语类型和对象集合的对象?

韩寒
2023-03-14

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

DtoA

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

@Data
public class DtoA {

    private String name;
    private String number;
    private List<String> aList;
}

DtoB

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

@Data
public class DtoB {
    private String name;
    private String phone;
    private List<String> bList;
}

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

数据适配器

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

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

下面是我的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);
    }
}

注意:我已经尝试编写CompareTo(通过将可比接口实现到Dto适配器类中),但是我无法使用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?
    }
}

共有3个答案

融建树
2023-03-14

我想比较列表的内容,而不用担心它们的顺序。

我已经实现了一个实用程序方法,它允许忽略顺序来比较列表。

该图书馆可从Maven Central获得:

<dependency>
  <groupId>org.softsmithy.lib</groupId>
  <artifactId>softsmithy-lib-core</artifactId>
  <version>2.0</version>
</dependency>

源代码可从GitHub获得。

另请注意实现可比的最佳实践:https://stackoverflow.com/a/46287029/506855

姚永年
2023-03-14

就像@Naman的答案一样,你可以覆盖方法等于,但尝试首先比较列表的长度,因为如果长度相同,你只需要检查第一个列表的元素是否在另一个列表中。

@Override
public boolean equals(Object o) {
    if (o == this) {
        return true;
    } 

    if (!(o instanceof DtoAdapter)) {
        return false;
    }

    DtoAdapter that = (DtoAdapter) o;

    return Objects.equals(nameText, that.nameText) && that.getXList().size() == xList.size() && that.getXList().containsAll(xList);

}
都超英
2023-03-14

您所期待的不是扩展一个< code>Comparable,而是该类的一个overrided < code > equals 实现(当然还有< code>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());
}

进一步参考Comparable的文档,该接口主要用于对元素排序,而不是用于相等比较:

该接口对实现它的每个类的对象强制执行总排序。这种排序被称为类的自然排序,类的compareTo方法被称为其自然比较方法。

 类似资料:
  • 问题内容: 我有两个从同一类实例化的java对象。 如果我将它们的两个属性都设置为完全相同的值,然后验证它们是否相同 但是,这些方法都不返回真实值。我已经检查了每个属性,并且它们匹配。 如何比较这两个对象以验证它们是否相同? 问题答案: 你需要提供自己的实现。 如果哈希表中有可能使用你的对象,则还应该重写。一个合理的实施将是该对象的字段的哈希码喜欢的东西结合起来:

  • 但是,这两种方法都不返回真值。我已经检查了每个属性,它们都匹配。 如何比较这两个对象以验证它们是相同的?

  • 在爪哇中。如果我们必须将一个对象与另一个对象进行比较。我们比较该对象中的每个字段。 学生 1 对象具有标记 1、标记 2、标记 3、名称、年龄作为字段。学生 2 对象具有标记 1、标记 2、标记 3、名称、年龄作为字段。因此,要检查2名学生是否相等...我们比较每个字段。 但是,如果 Student 对象有许多字段,该怎么办?学生1对象有标记1,标记2,标记3,名称,年龄,地址,颜色,类,国家,部

  • 问题内容: 我有两个像这样的对象数组: 我想知道数组是否相等。我定义的是相等的,因为array1中的每个值都与array2中该位置的值相同。因此,这两个数组将相等。 为什么最好找出这两个数组是否相等? 不是一个很深的等式,所以它是行不通的,我不知道是否遍历每个元素并进行比较是解决此问题的最佳,最有效的方法。有没有人有更好的建议? 编辑:我需要一个可以放入嵌套数组的等于。 问题答案: 使用。这项功能

  • 我正在实现一个排序列表类,在这个类中,我将对任何类型的对象进行排序,所以现在我想测试对象是否具有可比性, 我用这段代码覆盖了compareTo()方法:- 所以现在我需要给这些对象分配数字,像这样 但它总是给我一个例外:- 线程“main”中出现异常Java . lang . classcastexception:Java . lang . integer不能转换为java.lang.String

  • 假设我有两个列表,现在listOld包含旧员工信息,listNew包含新员工信息 我如何比较这两个列表并返回新列表,其中包含,添加的新员工列表,包含,删除的员工列表,包含上次更新已更改的员工的新列表? 我只能想到迭代列表和比较,可能最终几乎是O(n2)时间,这可以由任何util类更有效地完成吗?