Java List比较详解

本文详细探讨了Java中List的基本类型和对象类型的比较。通过测试发现,List的equals方法默认按元素顺序判断相等性。在实际项目中,由于顺序难以保证,因此提供了一种通用的List比较方法。此外,对于对象类型的List,重写equals和toString方法至关重要,以确保基于对象属性而非内存地址进行比较。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一)List基本类型比较

测试方式:声明两个List,分别往List中添加元素,只不过元素的顺序不一致,直接调用List的equals方法,查看返回结果。

package com.oysept.list;

import java.util.ArrayList;
import java.util.List;

public class ListCompare {

    public static void main(String[] args) {
        // 基本类型
        List<Object> list1 = new ArrayList<Object>();
        list1.add(111);
        list1.add("aaa");
        list1.add("bbb");
        list1.add("ccc");
		
        List<Object> list2 = new ArrayList<Object>();
        list2.add("aaa");
        list2.add("bbb");
        list2.add("ccc");
        list2.add(111);
		
        System.out.println("list1和list2中元素比较结果为: " + list1.equals(list2));
    }
}

打印效果图:预期结果应该返回true,结果返回false

 

查看一下List中equals源码,List继承了java.util.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());
}

从源码可以看出,List对象在equals时,是一行一行循环比较,又因为List底层是通过数组的方式实现,所以想得到预期的结果,必须保证两个List的元素size和顺序一致,才会返回true。

 

但在实际项目中,不可能一致保持两个List元素顺序一致,所以编写了一个通用一点的List equals方法。

/**
 * 比较两个List的元素值是否全部一致
 * @param t1
 * @param t2
 * @return
 */
public static <T> boolean listEquals(List<T> t1, List<T> t2) {
    if ((t1 == null && t2 == null) || t1 == t2) { // 为空or引用地址一致时
        return true;
    } else if (t1.size() != t2.size()) { // 数量一致, 过滤掉了list1中有{1,1,3},list2中有{1,3,4}的场景
        return false;
    }
		
    for (T t : t1) {
        if (!t2.contains(t)) { // equals比较
            return false;
        }
    }
    return true;
}

 

二)List对象类型比较

先创建一个Book的对象类,并重写equals和toString方法

重写equals的原因:当不重写equals方法时,比较的是两个对象存储的内存地址,对象不同内存地址肯定不一致,所以需要重写equals方法,具体判断对象的属性是否一致

package com.oysept.list;

public class Book {

    private String title;
    private Integer number;
	
    public Book() {}
    public Book(String title, Integer number) {
        this.title = title;
        this.number = number;
    }
	
    public String getTitle() {return title;}
    public void setTitle(String title) {this.title = title;}
	
    public Integer getNumber() {return number;}
    public void setNumber(Integer number) {this.number = number;}
	
    @Override
    public String toString() {
        return "[title=" + title + ", number=" + number + "]";
    }
	
    @Override
    public boolean equals(Object o) {
        if (!(o instanceof Book)) {
            return false;
        }
        Book book = (Book) o;
        if (this.title.equals(book.getTitle()) 
            && this.number.equals(book.getNumber())) { // 由于number是Integer类型, 所以需要用equals比较
            return true;
        }
        return false;
    }
}

测试源码:

package com.oysept.list;

import java.util.ArrayList;
import java.util.List;

public class ListCompare {

    public static void main(String[] args) {
        // 对象类型, List元素顺序不一致
        List<Book> list5 = new ArrayList<Book>();
        list5.add(new Book("BBB", 222));
        list5.add(new Book("CCC", 111));
        list5.add(new Book("AAA", 333));
		
        List<Book> list6 = new ArrayList<Book>();
        list6.add(new Book("AAA", 333));
        list6.add(new Book("BBB", 222));
        list6.add(new Book("CCC", 111));
        System.out.println("两个List比较结果为: " + listEquals(list5, list6));
    }

    /**
     * 比较两个List的元素值是否全部一致
     * @param t1
     * @param t2
     * @return
     */
    public static <T> boolean listEquals(List<T> t1, List<T> t2) {
        if ((t1 == null && t2 == null) || t1 == t2) { // 为空or引用地址一致时
            return true;
        } else if (t1.size() != t2.size()) { // 数量一致, 过滤掉了list1中有{1,1,3},list2中有{1,3,4}的场景
            return false;
        }
		
        for (T t : t1) {
            if (!t2.contains(t)) { // equals比较
                return false;
            }
        }
        return true;
    }
}

控制台打印效果图为:

 

识别二维码关注个人微信公众号

本章完结,待续,欢迎转载!
 
本文说明:该文章属于原创,如需转载,请标明文章转载来源!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值