代码之家  ›  专栏  ›  技术社区  ›  ufk

我怎么检查两个数组列表是否不同,我不在乎发生了什么变化

  •  35
  • ufk  · 技术社区  · 15 年前

    如何检查两个数组列表之间是否存在差异?我不在乎有什么区别,我只是想知道它们是否不一样。

    我每分钟从数据库中提取分数列表,只有当我提取的分数列表与一分钟前提取的不同时,我才会将其发送给客户。

    现在,arraylist的值实际上是我创建的一个类(包含名称、lvl、rank、score)。

    我需要实施吗 equals() 在上面?

    6 回复  |  直到 7 年前
        1
  •  6
  •   Traveling Salesman    8 年前

    下面是一个简单的方法,它检查两个数组列表是否包含相同的值,而不管它们的顺序如何。

     //the name of the method explains it well...
        public boolean isTwoArrayListsWithSameValues(ArrayList<Object> list1, ArrayList<Object> list2)
        {
            //null checking
            if(list1==null && list2==null)
                return true;
            if((list1 == null && list2 != null) || (list1 != null && list2 == null))
                return false;
    
            if(list1.size()!=list2.size())
                return false;
            for(Object itemList1: list1)
            {
                if(!list2.contains(itemList1))
                    return false;
            }
    
            return true;
        }
    
        2
  •  79
  •   Community CDub    8 年前

    论“相同”的定义

    正如约阿希姆指出的,对于大多数应用, List.equals(Object o) 定义工作:

    将指定的对象与此列表比较是否相等。退换商品 true 如果且仅当指定的对象也是列表时,两个列表的大小相同,并且两个列表中所有对应的元素对都相等。(两个元素) e1 e2 是否相等 (e1==null ? e2==null : e1.equals(e2)) 换言之,如果两个列表包含相同的元素,并且顺序相同,则它们被定义为相等。此定义确保 equals 方法在 List 接口。

    不过,这可能无法按预期工作,具体取决于您使用它的方式。如果你有 List<int[]> 例如,它不太起作用,因为数组继承 等于 Object 它将相等定义为引用标识。

        List<int[]> list1 = Arrays.asList(new int[] { 1, 2, 3 });
        List<int[]> list2 = Arrays.asList(new int[] { 1, 2, 3 });
        System.out.println(list1.equals(list2)); // prints "false"
    

    另外,两个具有不同类型参数的列表可以 等于 :

        List<Number> list1 = new ArrayList<Number>();
        List<String> list2 = new ArrayList<String>();
        System.out.println(list1.equals(list2)); // prints "true"
    

    您还提到列表必须包含具有相同类型的元素。这里还有另一个例子,元素没有相同的类型,但是它们是 等于 :

        List<Object> list1 = new ArrayList<Object>();
        List<Object> list2 = new ArrayList<Object>();
        list1.add(new ArrayList<Integer>());
        list2.add(new LinkedList<String>());
        System.out.println(list1.equals(list2)); // prints "true"
    

    因此,除非你清楚地定义平等对你意味着什么,否则问题的答案可能会非常不同。不过,为了最实际的目的, List.equals 应该足够了。


    论实施 等于

    更新后的信息表明 Listar 会做得很好的, 假如 元素实现 等于 正确地(因为 List<E>.equals 调用 E.equals 关于非 null -元素,根据上述API文档)。

    所以在这种情况下,如果我们有,比如 List<Player> 然后 Player 必须 @Override equals(Object o) 归来 如果 o instanceof Player 在相关领域,他们都是 等于 (用于参考类型)或 == (对于原语)。

    当然,当你 @Override equals ,你也应该 @Override int hashCode() . 几乎不可接受的最低要求是 return 42; 稍微好一点的是 return name.hashCode(); ;最好是使用一个涉及您定义的所有字段的公式。 等于 . 一个好的IDE可以自动生成 equals/hashCode 方法。

    也见

    • 有效Java第二版
      • 第8条:当优先考虑等于
      • 第9项:重写等于时始终重写哈希代码

    API链接

    相关问题

    等值/哈希码 联合体:

    等于 VS = :

        3
  •  11
  •   Joachim Sauer    15 年前

    使用 equals() . 只要列表中的元素实现 等式() 正确,它将返回正确的值。

    除非要忽略值的顺序,否则应将值转储为两个 Set 对象,并使用 等式() .

        4
  •  2
  •   frostymarvelous    10 年前

    正如@joachim sauer在他的答案中提到的,如果列表相等,并且它们的内容实现正确的相等,equals应该有效。但是,如果项目不在同一个“顺序”中,它就不应该工作,因为它不使用contains进行检查。在这个意义上,它检查@jarnbjo所提到的“严格”的平等性。

            //From android's Arraylist implementation
            Iterator<?> it = that.iterator();
            for (int i = 0; i < s; i++) {
                Object eThis = a[i];
                Object eThat = it.next();
                if (eThis == null ? eThat != null : !eThis.equals(eThat)) {
                    return false;
                }
            }
    

    然而,我想要一些不同的行为,我不在乎秩序或其他类似的事情。我只想确保这两个不包含相同的物品。 我的解决方案,

        //first check that both are not null and are of same length. (not shown here)
        //if both match, pull out the big guns as below
        ...
        List<Object> comparedList = new ArrayList<>(listOne);
        comparedList.removeAll(listTwo);
        if(comparedList.size() != 0) //there are differences between the two
    

    因为它循环了两次,第一次出现在 removeAll 然后在 contains 它是由 移除所有 .

    我的单子肯定很短,所以我不介意被打中。

        5
  •  2
  •   Robert Londo    7 年前

    您可以将它们转换为字符串,然后进行如下比较

    list1.toString().equals(list2.toString())
    
        6
  •  -1
  •   Community CDub    8 年前

    您还可以检查arraylist,如下所示:

    public  boolean equalLists(List<String> one, List<String> two){     
    if (one == null && two == null){
        return true;
    }
    
    if((one == null && two != null) 
      || one != null && two == null
      || one.size() != two.size()){
        return false;
    }
    
    //to avoid messing the order of the lists we will use a copy
    //as noted in comments by A. R. S.
    one = new ArrayList<String>(one); 
    two = new ArrayList<String>(two);   
    
    Collections.sort(one);
    Collections.sort(two);      
    return one.equals(two);
    }
    

    多亏了 @Jacob