【问题标题】:How to check if two arraylist are the same (Unit test with JUnit)如何检查两个数组列表是否相同(使用 JUnit 进行单元测试)
【发布时间】:2018-02-25 20:47:53
【问题描述】:

在您将我的问题标记为重复之前,我已在其他帖子中尝试过解决方案,但没有奏效。这就是我所拥有的

Clientes Cliente1 = new Clientes(1,PinturasCliente1,ColoresCliente1);
Clientes Cli= new Clientes(1,PinturasCliente1,ColoresCliente1);
ArrayList<Clientes> ListaClientes = new ArrayList<Clientes>();
ArrayList<Clientes> ClientesMetodo =  new ArrayList<Clientes>();
ListaClientes.add(Cliente1);
ClientesMetodo.add(Cli);

Assert.assertEquals(ListaClientes, ClientesMetodo);

这个返回错误,顺便说一下PinturasCliente1和ColoresCliente1也是ArrayList。

那么,我如何测试ListaClientes 和ClientesMetodo 没有相同的对象,但他们添加的对象具有相同的信息。

【问题讨论】:

  • 通过在 Clientes 类中正确覆盖 equals 方法。
  • 这里是the docs
  • 谢谢,我去看看@FedericoPeraltaSchaffner
  • 来吧,在这里搜索关于 equals 方法的问题,阅读互联网上的文章。基本上,equals 方法告诉两个实例是否语义相等,即如果类Person 的两个不同实例具有相同的名称、相同的姓氏、相同的日期和出生地和相同的身份证/社会安全号码,或者如果他们只有相同的身份证号码,则返回 true 就足够了。我的意思是,如果他们真的代表同一个人。

标签: java maven unit-testing junit


【解决方案1】:

您应该在要添加到列表中的对象的类上覆盖 equals 方法。

来自javadoc:

公共布尔等于(对象 obj)

指示其他对象是否“等于”这个对象。

equals 方法在非 null 上实现等价关系 对象引用:

  • 它是自反的:对于任何非空引用值 x,x.equals(x) 应该返回 true。
  • 它是对称的:对于任何非空引用值 x 和 y,当且仅当 y.equals(x) 返回时,x.equals(y) 才应该返回 true 是的。
  • 它是可传递的:对于任何非空引用值 x、y 和 z,如果 x.equals(y) 返回 true 并且 y.equals(z) 返回 true,则 x.equals(z) 应该返回 true。
  • 一致:对于任何非空引用值 x 和 y,多次调用 x.equals(y) 始终返回 true 或 始终返回 false,前提是 equals 中没有使用任何信息 对象的比较被修改。
  • 对于任何非空引用值 x,x.equals(null) 应该返回 false。

Object类的equals方法实现了最区分 对象上可能的等价关系;也就是说,对于任何非空 参考值 x 和 y,当且仅当 x 和 y 指的是同一个对象(x == y 的值为 true)。

注意,一般需要重写hashCode方法 每当此方法被覆盖时,以保持一般 hashCode 方法的契约,它规定相等的对象必须 具有相同的哈希码。

参数: obj - 要与之比较的参考对象。回报: 如果此对象与 obj 参数相同,则为 true;否则为假。

注意:如果您在给定类中覆盖 equals 方法,也建议覆盖 hashCode 方法。

【讨论】:

    【解决方案2】:

    定义了AbstractList.equals():

    public boolean equals(Object o) {
        if (o == this)
            return true;
        if (!(o instanceof List))
            return false;
    
        ListIterator<E> e1 = listIterator();
        ListIterator<?> e2 = ((List<?>) o).listIterator();
        while (e1.hasNext() && e2.hasNext()) {
            E o1 = e1.next();
            Object o2 = e2.next();
            if (!(o1==null ? o2==null : o1.equals(o2)))
                return false;
        }
        return !(e1.hasNext() || e2.hasNext());
    }
    

    所以它使用 o1.equals(o2) 来比较每个元素。在您的情况下,它是客户。但是Clientes.equals()默认是Object.equals(),它是这样定义的:

    public boolean equals(Object obj) {
        return (this == obj);
    }
    

    显然,Cliente1 != Cli。 因此,您应该在 Clientes 中覆盖 Object.equlas()。您可以通过添加来检查这一点

    public boolean equals(Object o) { return true; }
    

    在客户中。然后专注于执行。对于 PinturasCliente1 和 ColoresCliente1,最好也为每个类实现自己的 equals(),以防它们不是同一个对象。

    【讨论】:

      【解决方案3】:

      您可以覆盖您的 equals 方法,即所有对象都来自 Object,

      如果你使用maven / gradle,你可以导入Lombok project

      <dependency>
          <groupId>org.projectlombok</groupId>
          <artifactId>lombok-maven</artifactId>
          <version>1.16.20.0</version>
          <type>pom</type>
      </dependency>
      

      并使用它自动生成equals 和hashcode 方法。

      @EqualsAndHashCode
      public class Clientes {
      
      }
      

      【讨论】:

        【解决方案4】:

        如果你实现 equals() 和 hashCode() 方法并使用 AbstractList 中的 equals() 方法,如果只有两个列表包含相同顺序的相同元素,你的程序就可以工作。 如果两个列表包含相同的元素但顺序不同,那么即使两个列表的内容相同,它也会返回 false。我不知道这是否是您的要求,但如果是,那么您需要编写自己的逻辑来比较列表。

        【讨论】:

          猜你喜欢
          • 2017-03-25
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-04-19
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多