Java - equals 方法

By sunwc 2023-03-21 Java

Object 的 euqals() 與 == 作用是相同的

是比較兩個物件的記憶體地址是否相同

    public boolean equals(Object obj) {
        return (this == obj);
    }
  • String, java.util.Date, File, wrapper class的 equals() 都已經覆寫Object的 euqals(),比較的不是兩個物件的地址值是否相等,而是比較實體內容是否相同
String s1 = new String("sunwc");
String s2 = new String("sunwc");
System.out.println(s1.equals(s2)); //true

Date date1 = new Date(32432525324L);
Date date2 = new Date(32432525324L);
System.out.println(date1.equals(date2)); //true

自定義類別 覆寫 equals()

public class Customer {
	
	private int age;
	private String name;
	
	
	public Customer() {
		super();
	}
	
	
	public Customer(int age, String name) {
		super();
		this.age = age;
		this.name = name;
	}


	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	
	
	/**
     * 手動實現
	 * 覆寫的原則:比較兩個物件的實體內容(即name和age)是否相同
	 */
	@Override
	public boolean equals(Object obj) {
		
		if (this == obj) {
			return true;
		}
		
		if (obj instanceof Customer) {
			Customer customer = (Customer) obj;
			
			return customer.age == this.age && customer.name.equals(this.name);
		}
		return false;
	}
}
	/**
	 * IDE 自動生成 equals() 覆寫:比較兩個物件的實體內容(即name和age)是否相同
	 */
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Customer other = (Customer) obj;
		if (age != other.age)
			return false;
		if (name == null) {
			if (other.name != null)
				return false;
		} else if (!name.equals(other.name))
			return false;
		return true;
	}

測試類

public class CustomerTest {
	
	public static void main(String[] args) {
		
		Customer c1 = new Customer(18, "Lucy");
		Customer c2 = new Customer(18, "Lucy");
		
		System.out.println(c1.equals(c2)); //true
	}

}

理解 Collection API: contains(), containsAll(), remove(), removeAll()判斷 與 Collection元素擁有equals() 的邏輯判斷有關,主要看該 equals() 是比較記憶體地址 還是 屬性內容?

/**
 * @author sunwc
 * @create 2023-03-28 上午 09:56
 */
public class CollectionTest {

    @Test
    public void collectionTest() {

        Collection collection = new ArrayList<>();

        Person person = new Person("Jerry", 20);
        collection.add(person);

        System.out.println(collection.size()); // 1

        boolean contains = collection.contains(person); // true
        System.out.println(contains);

        // 在自定義Person尚未 Override equals()時,默認是使用Object類的 equals(),比較的是 == 的概念
        // 因此 比較的是 記憶體的地址
        // 所以這時候如果問 new Person("Jerry", 20) 是否有包含在集合中時,就會回傳false
        
        // 但是如果Person類 Override equals()後,比較的就會是 Person類中的屬性了
        // 所以這時候如果問 new Person("Jerry", 20) 是否有包含在集合中時,就會回傳true
        System.out.println(collection.contains(new Person("Jerry", 20)));

        // collection.remove() 與 collection.contains() 的調用的結果,會隨著自定義類別是否覆寫過 equals() 而有不同
        boolean jerry = collection.remove(new Person("Jerry", 20));
        System.out.println(jerry);

    }
}

class Person {
    private String name;
    private int age;

    public Person() {
    }

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        final StringBuilder sb = new StringBuilder("Person{");
        sb.append("name='").append(name).append('\'');
        sb.append(", age=").append(age);
        sb.append('}');
        return sb.toString();
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Person person = (Person) o;
        return age == person.age && Objects.equals(name, person.name);
    }

}

總結

向 interface Collection 的實現類別的物件容器中,新增元素 obj 時,要求 obj 所在類別要覆寫 equals()

補充知識

Collection 集合

  • 特性:元素有序性、元素可重複性
  • removeAll():求差集 => 刪除兩個集合中一樣的所有元素,而保留其他不一樣的元素
  • retainAll():求交集 => 刪除兩個集合中所有不一樣的元素,而保留其他一樣的元素
  • 集合 –> array
Collection collection = new ArrayList<>();

collection.add(123);
collection.add(456);

Object[] arr = collection.toArray();
System.out.println(Arrays.toString(arr)); // [123, 456]
  • array –> 集合
List<Integer> list = Arrays.asList(new Integer[]{123,456});
System.out.println(list); // [123, 456]