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());
		}
	}
}
相关文章
相关标签/搜索