• 从源码分析:java中怎样判断List是否相等(euqlas()方法)


    Java中两个基本类型,比如说两个整型非常容易判断其是否相等,那么如果是两个List的实例呢?

    测试代码

    List<Integer> list1 = new ArrayList<>();
    List<Integer> list2 = new ArrayList<>();
    List<Integer> list3 = new ArrayList<>();
    list1.add(1);
    list1.add(2);
    list1.add(3);
    list2.add(1);
    list2.add(2);
    list2.add(3);
    list3.add(4);
    list3.add(5);
    System.out.println(list1.equals(list2));
    System.out.println(list1.equals(list3));
    

    代码中创建了3个List的实例:list1、list2、list3,其中前两者的内部的内容是相同的,且都与list3不同。初始化完几个list实例后,判断list1与list2和list1与list3分别是否相等。

    输出:

    true
    false
    

    说明,在Java中,Listequals()方法,是根据list实例内的内容来进行判断的,而不是简单的”不是同一个引用对象即判false”。

    解释

    让我们看一下Listequals()方法的注释:

           /**
         * Compares the specified object with this list for equality.  Returns
         * <tt>true</tt> if and only if the specified object is also a list, both
         * lists have the same size, and all corresponding pairs of elements in
         * the two lists are <i>equal</i>.  (Two elements <tt>e1</tt> and
         * <tt>e2</tt> are <i>equal</i> if <tt>(e1==null ? e2==null :
         * e1.equals(e2))</tt>.)  In other words, two lists are defined to be
         * equal if they contain the same elements in the same order.  This
         * definition ensures that the equals method works properly across
         * different implementations of the <tt>List</tt> interface.
         *
         * @param o the object to be compared for equality with this list
         * @return <tt>true</tt> if the specified object is equal to this list
         */
        boolean equals(Object o);
    

    从注释里可以看到,判断两个List实例相等,当且仅当:

    • 两个list的size()相同,即大小相同
    • 在两个list中,每一个对应元素都要相等(注:这里判断两个元素e1和e2相等的方法为:e1==null ? e2==null : e1.equals(e2),即两个元素要么同为null,要么调用e1.equals(e2)判断两者相等)

    换句话说,总结起来就是,两个列表必须按相同顺序储存了同样的元素。

    源码

    由于List是一个接口,其实现代码不会在List.java中,而继承List接口的类又有很多,所以equals方法的具体实现放在了抽象类AbstractList.java中,而其它具体的类,如ArrayList、LinkedList等,便继承这个AbstractList类,来使用其中定义的方法。

    在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());
        }
    

    在源码中,我们可以看到,首先判断输入的参数Object o中的o是否是一个实现了List接口的类的实例,若不是,则直接返回false。

    然后,对于两个List的实例,获取其迭代器e1、e2,之后,利用迭代器,每次取两个迭代器的下一个元素,并递归地调用元素的equals方法判断这两个元素是否相等,若不相等,则返回false。

    最后,看两个迭代器是否同时遍历完,若同时遍历完,则返回true,否则,返回false。在这里,是用这种方法比较两者的大小是否相等。

  • 相关阅读:
    SQL所有者更改问题
    人生路上对我影响最大的三位老师
    自我介绍
    Ural_1146. Maximum Sum (DP)
    Ural_1654. Cipher Message(栈)
    Ural_1333. Genie Bomber 2
    POJ_2112 Optimal Milking(网络流)
    Ural_1031.Railway Ticket (DP)
    Ural_1030. Titanic
    Ural_1207. Median on the Plane(计算几何)
  • 原文地址:https://www.cnblogs.com/liulaolaiu/p/11744401.html
Copyright © 2020-2023  润新知