黑马程序员技术交流社区

标题: 谁能总结一下集合中comparaTo和equals的用法 [打印本页]

作者: librazeng    时间: 2013-5-23 16:23
标题: 谁能总结一下集合中comparaTo和equals的用法
本帖最后由 librazeng 于 2013-5-24 08:18 编辑

在玩集合的时候,发现不明白为什么类中覆写了equals和comparaTo方法,添加到集合中就能自动排序了。
这是为什么呀,添加的时候,上一个元素和下一个元素是怎么比较的啊?
自己写的代码,有点看不懂了。
  1. public class Person extends Object implements Comparable<Person>{
  2.         /**
  3.          * @param args
  4.          */
  5.                 private String name;
  6.                 private int age;
  7.                 public String getName() {
  8.                         return name;
  9.                 }
  10.                 public void setName(String name) {
  11.                         this.name = name;
  12.                 }
  13.                 public int getAge() {
  14.                         return age;
  15.                 }
  16.                 public void setAge(int age) {
  17.                         this.age = age;
  18.                 }
  19.                 public int compareTo(Person p){
  20.                         int temp=this.name.compareTo(p.name);
  21.                         return temp==0?this.age-p.age:temp;
  22.                 }
  23.                 @Override
  24.                 public int hashCode() {
  25.                         final int prime = 31;
  26.                         int result = 1;
  27.                         result = prime * result + age;
  28.                         result = prime * result + ((name == null) ? 0 : name.hashCode());
  29.                         return result;
  30.                 }
  31.                 @Override
  32.                 public boolean equals(Object obj) {
  33.                         if (this == obj)
  34.                                 return true;
  35.                         if (obj == null)
  36.                                 return false;
  37.                         if (getClass() != obj.getClass())
  38.                                 return false;
  39.                         Person other = (Person) obj;
  40.                         if (age != other.age)
  41.                                 return false;
  42.                         if (name == null) {
  43.                                 if (other.name != null)
  44.                                         return false;
  45.                         } else if (!name.equals(other.name))
  46.                                 return false;
  47.                         return true;
  48.                 }
  49.                 public Person() {
  50.                         super();
  51.                 }
  52.                 public Person(String name, int age) {
  53.                         super();
  54.                         this.name = name;
  55.                         this.age = age;
  56.                 }
  57. }
复制代码
  1. public class GenericAdvanceDemo {
  2.         /**
  3.          *
  4.          * @param args
  5.          */
  6.         public static void main(String[] args) {
  7.                 TreeSet<Person> ts=new TreeSet<Person>();//new ComparatorByName()
  8.                 ts.add(new Person("xiaotao",20));        
  9.                 ts.add(new Person("taoran",19));        
  10.                 ts.add(new Person("wangtaoran",18));        
  11.                 ts.add(new Person("anneng",25));        
  12.                 ts.add(new Person("haoyuan",20));        
  13.                 ts.add(new Person("haoyuan",20));        //添加进入后,元素之间是怎么比较的啊??
  14.                 for(Iterator<Person> it=ts.iterator();it.hasNext();){
  15.                         Person p=it.next();
  16.                         System.out.println(p.getName()+p.getAge());
  17.                 }
复制代码
谢谢各位!

作者: 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