黑马程序员技术交流社区
标题:
谁能总结一下集合中comparaTo和equals的用法
[打印本页]
作者:
librazeng
时间:
2013-5-23 16:23
标题:
谁能总结一下集合中comparaTo和equals的用法
本帖最后由 librazeng 于 2013-5-24 08:18 编辑
在玩集合的时候,发现不明白为什么类中覆写了equals和comparaTo方法,添加到集合中就能自动排序了。
这是为什么呀,添加的时候,上一个元素和下一个元素是怎么比较的啊?
自己写的代码,有点看不懂了。
public class Person extends Object implements Comparable<Person>{
/**
* @param args
*/
private String name;
private int 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;
}
public int compareTo(Person p){
int temp=this.name.compareTo(p.name);
return temp==0?this.age-p.age:temp;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + age;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Person other = (Person) 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 Person() {
super();
}
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
}
复制代码
public class GenericAdvanceDemo {
/**
*
* @param args
*/
public static void main(String[] args) {
TreeSet<Person> ts=new TreeSet<Person>();//new ComparatorByName()
ts.add(new Person("xiaotao",20));
ts.add(new Person("taoran",19));
ts.add(new Person("wangtaoran",18));
ts.add(new Person("anneng",25));
ts.add(new Person("haoyuan",20));
ts.add(new Person("haoyuan",20)); //添加进入后,元素之间是怎么比较的啊??
for(Iterator<Person> it=ts.iterator();it.hasNext();){
Person p=it.next();
System.out.println(p.getName()+p.getAge());
}
复制代码
谢谢各位!
作者:
librazeng
时间:
2013-5-23 20:58
求关注求回答啊
作者:
蔡增辉
时间:
2013-5-23 23:07
这个自动排序,是 TreeSet 集合的功能,它本身要求其中的元素具有可比较性,所以相应的类要实现compareable接口;
实现compareable接口就必须复写其中的 compareTo 方法,该方法为对象的比较大小提供了规则;
针对你这个程序,其实只需要实现实现compareable接口并复写其中的 compareTo 方法就可以了;
老毕视频中复写 hashCode 方法和 equals 方法,是为了把给类的对象存储在HashSet 集合中做准备的,你这里用不到;
作者:
Jacky_Chen1990
时间:
2013-5-23 23:14
TreeSet的排序分为两种。一个是自然排序,一个是客户端排序。
何谓自然排序,就是排序的对象本身实现了Comparable接口,复写了compareTo方法,按照其中的条件排序。
何谓客户端排序,就是自己写一个比较器XXComparator且实现了Comparator接口,复写compare方法,然后进行排序。
另外equals方法和hashCode方法的一些知识点:
实际上,所有实现 Comparable 的 Java 核心类都具有与 equals 一致的自然排序。
java.math.BigDecimal 是个例外,它的自然排序将值相等但精确度不同的 BigDecimal 对象(比如 4.0 和 4.00)视为相等。
为了保证你能够排序正确,compareTo()方法和equals(0方法必须按照相同的规则进行比较。所以需要复写equals方法,而如果你复写了equals方法,则就要重写hashCode方法。
作者:
Super_Class
时间:
2013-5-23 23:46
comparaTo()方法是实现Comparable接口的实现方法。
TreeMap集合中,可以对元素进行排序。如果是自定义对象作为键。那么这个对象就要实现Comparable接口
相对于equals来说。equals方法使用就更为广泛。equals是OBject类的方法。如果需要自己定义“相等”的方式
当此方法被重写时,通常有必要重写 hashCode 方法,以维护 hashCode 方法的常规协定,该协定声明相等对象必须具有相等的哈希码。
作者:
刘胜寒
时间:
2013-5-24 00:31
equals 是用来比较地址值,但是对于基本类型和String类型来说,有些被复写了。。。所以就不是很靠谱。
compareTo()是用来定义应用类型比较大小用的。
要现实Compareable接口。
应用类型使用TreeSet一定要使泛型类型具有可比较性。
对于数组Arrays.sort(); 这个也要实现这个东西。
不现实可以使用自定义比较器。
作者:
袁梦希
时间:
2013-5-24 01:02
楼主你好,如果问题以解决,请修改分类,谢谢合作。
作者:
袁梦希
时间:
2013-5-24 01:02
如果不知道咋改请看下我的个性签名
作者:
刘胜寒
时间:
2013-5-24 01:09
袁梦希 发表于 2013-5-24 01:02
楼主你好,如果问题以解决,请修改分类,谢谢合作。
感觉还凑合。
作者:
librazeng
时间:
2013-5-24 08:17
我总结一下吧,看对不对:
覆盖hashcode和equals,比较对象是否相同
HashSet
为了保证集合元素唯一性,哈希算法是先判断元素位置hashCode,再判断元素内容是否相同。存储的元素,一般要覆写hashCode和equals方法,以实现自己定义的位置和内容比较条件。
TreeSet
1.让元素自身具备比较性:
类继承Comparable,覆写comparaTo(Object obj)方法,这样可以比较类对象的大小,类就有了自然排序功能;
2.让集合具备比较性:
定义一个类实现Comparator接口,覆写compare(T o1,T o2)方法,比较元素大小。将这个类对象(比较器)通过构造函数传给集合。比较器优先级比元素高,更常用。
3.add方法,调用的时候,内部就进行了比较,没看源码,应该比较复杂。
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2