Java中的equals方法和自定義比較器

Object中的equals()方法默認是按地址比較,而不按內容進行比較,java

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

在String中覆寫了Object中的equals方法,以用於判斷字符串是否相同,安全

   public boolean equals(Object anObject) {
        if (this == anObject) {
            return true;
        }
        if (anObject instanceof String) {
            String anotherString = (String) anObject;
            int n = value.length;
            if (n == anotherString.value.length) {
                char v1[] = value;
                char v2[] = anotherString.value;
                int i = 0;
                while (n-- != 0) {
                    if (v1[i] != v2[i])
                            return false;
                    i++;
                }
                return true;
            }
        }
        return false;
    }

"上帝"Object中equals方法能夠被子類重寫,而後多態調用,當咱們要自定義對象比較時通常要覆寫equals方法,好比有Person對象,同姓名同年齡,視爲同一個對象,數據結構

    public boolean equals(Object obj)
	{
		if(!(obj instanceof Person))
        	return false;
		Person p = (Person)obj;
		return this.name.equals(p.name) && this.age == p.age;
	}    

List集合判斷元素是否相同,依據是元素的equals方法。函數

若是要將自定義對象存入到HashSet中,則要覆寫hashCode()和equals():this

    public int hashCode()
	{
		//System.out.println(this.name+"....hashCode");
		return name.hashCode()+age*11;
	}

	public boolean equals(Object obj)
	{
		if(!(obj instanceof Person))
			return false;
		Person p = (Person)obj;
		
		//System.out.println(this.name+"....equals..."+p.name);
		return this.name.equals(p.name) && this.age==p.age;
	} 

HashSet:底層數據結構是哈希表。是線程不安全的。不一樣步。
            HashSet是如何保證元素惟一性的呢?是經過元素的兩個方法,hashCode和equals來完成。
            若是元素的HashCode值相同,纔會判斷equals是否爲true。
            若是元素的hashcode值不一樣,不會調用equals。
注意,對於判斷元素是否存在,以及刪除等操做,依賴的方法是元素的hashcode和equals方法。
spa


自定義比較器:線程

當元素自身不具有比較性,或者具有的比較性不是所須要的,這時須要讓容器自身具有比較性。
當兩種排序都存在時,以比較器爲主。
方式1:定義一個類,實現Comparable接口,覆蓋compareTo方法。code

class Student implements Comparable//該接口強制讓學生具有比較性。
{
	private String name;
	private int age;

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

	//先按年齡從小到大排序,若是年齡相同,再按名字
	public int compareTo(Object obj)
	{
		if(!(obj instanceof Student))
			throw new RuntimeException("不是學生對象");
		Student s = (Student)obj;
		
		if(this.age>s.age)
			return 1;
		if(this.age==s.age)
		{
			return this.name.compareTo(s.name);
		}
		return -1;		
	}

	public String getName()
	{
		return name;
	}
	public int getAge()
	{
		return age;
	}
}

class Test 
{
	public static void main(String[] args) 
	{
		TreeSet ts = new TreeSet(new Mycompare());

		ts.add(new Student("lisi02",22));
		ts.add(new Student("lisi02",21));
		ts.add(new Student("lisi007",20));
		ts.add(new Student("lisi09",19));
		ts.add(new Student("lisi06",18));
		ts.add(new Student("lisi06",18));
		ts.add(new Student("lisi007",29));
		
		Iterator it = ts.iterator();
		while(it.hasNext())
		{
			Student stu = (Student)it.next();
			System.out.println(stu.getName()+"..."+stu.getAge());
		}
	}
}

方式2:定義一個類,還要再自定義一個比較器實現Comparator接口,覆蓋compare方法。對象

定義了比較器,將比較器對象做爲參數傳遞給TreeSet集合的構造函數。 blog

class Student
{
	private String name;
	private int age;

	Student(String name,int age)
	{
		this.name = name;
		this.age = age;
	}
	
	public String getName()
	{
		return name;
	}
	public int getAge()
	{
		return age;
	}
}

//自定義比較器:先按名字來排序,若是名字相同再按年齡
class Mycompare implements Comparator
{
	public int compare(Object o1,Object o2)
	{
		Student s1 = (Student)o1;
		Student s2 = (Student)o2;

		int num = s1.getName().compareTo(s2.getName());
		if (num == 0)
			return new Integer(s1.getAge()).compareTo(new Integer(s2.getAge()));
		return num;
	}
}
class Test 
{
	public static void main(String[] args) 
	{
		TreeSet<Student> ts = new TreeSet<Student>(new Mycompare());

		ts.add(new Student("lisi02",22));
		ts.add(new Student("lisi02",21));
		ts.add(new Student("lisi007",20));
		ts.add(new Student("lisi09",19));
		ts.add(new Student("lisi06",18));
		ts.add(new Student("lisi06",18));
		ts.add(new Student("lisi007",29));
				
		for (Iterator<Student> it = ts.iterator();it.hasNext() ; )
		{
			Student stu = it.next();
			System.out.println(stu.getName()+".."+stu.getAge());
		}
	}
}
相關文章
相關標籤/搜索