黑马程序员技术交流社区
标题:
关于Comparable和Comparator的用法
[打印本页]
作者:
陈雨
时间:
2013-4-15 10:59
标题:
关于Comparable和Comparator的用法
本帖最后由 陈雨 于 2013-4-16 08:08 编辑
有点弄不清到底什么时候用Comparable和Comparator。毕老师的视疲里讲当元素自己具备比较性时用Comparable,当元素不具备比较性,或者排序的方式不是自己想要的就用Comparator。我想问什么时候就叫元素自身不具备比较性?当用TreeSe和TreeMap集合时?还是说元素自己本身的特性,比如自然顺序(数字,字母啊),这时他们自己就具备比较性吗?
作者:
mvplee
时间:
2013-4-15 11:05
在简单Java类设计之初,如果考虑到需要排序、比较,简单Java类实现Comparable接口,在类的内部具有了比较规则。
Comparator也是比较器,你可以理解为“挽救”的比较,原类不觉被比较规则,需要类似于“第三方”提供比较规则,就使用Comparator。
这些都是纯概念性的,内部实现比较规则都是一样的。!
作者:
殇_心。
时间:
2013-4-15 11:08
举个例子吧:
比如说人和人比较的时候。
这个很抽象吧? 到底比较什么,或者说没有比较性可言。
这个时候你就可以定义你的比较方式,如年龄。
当年龄一样的时候,又该按什么比较啊。 这种情况下就用Comparator比较器。
作者:
刘永建
时间:
2013-4-15 11:28
你要搞清楚,Comparable和Comparator都是用来比较的接口,它们常常被用在自定义类型中,也就是设计自己的比较方法
作为接口的代表 interface Comparable 接口:
Arrays类中的sort方法承诺可以对对象数组进行排序,但要求对象所属的类必须实现了 Comparable接口,并且重写了其中的comparaTo方法
而对于Comparator接口,需要重写其中的compar方法,当然TreeSet是有序的,这需要你在生成对象的时候传入一个实现了Comparator接口的对象,
作为比较的依据;
希望对你有帮助,不懂得话可以再联系我!
大家一起加油!
作者:
本人已死
时间:
2013-4-15 11:45
public class TreeSet<E>extends AbstractSet<E>implements NavigableSet<E>, Cloneable, Serializable基于 TreeMap 的 NavigableSet 实现。使用元素的自然顺序对元素进行排序,或者根据创建 set 时提供的 Comparator 进行排序,具体取决于使用的构造方法。
public class TreeMap<K,V>extends AbstractMap<K,V>implements NavigableMap<K,V>, Cloneable, Serializable基于红黑树(Red-Black tree)的 NavigableMap 实现。该映射根据其键的自然顺序进行排序,或者根据创建映射时提供的 Comparator 进行排序,具体取决于使用的构造方法。
因为treeset,treemap实现了Comparator 所以具有排序的特性
Comparable排序都都是一些已有的类的对象
而我们一般自己写的类的对象需要按我们自己的方式排序就需要Comparator 来实现,通过复写compare() 和equals()方法
作者:
gerenvip
时间:
2013-4-15 11:48
这个主要清楚分别用在什么地方,就很容易明白:
TreeSet我们知道可以对Set集合中的元素进行排序
而排序有两种方法:
1.让元素自身具有比较性,举个例子。我们知道Person类的对象是不具备比较性的,而我们又需要对对象进行排,所以我们可以人为的定义,让对象具有比较性。明白这一点后,就好似怎么实现可比较性了。这时第一种方法就出现了。让Person类实现comparable接口,覆盖接口中的compareTo方法
这种方式也叫做元素的自然排序,或者叫做默认顺序。
所谓元素自身不具备比较性,其实很好理解。例如两个人有比较性吗?没有,要比较也得是你定义比较规则,例如谁年龄长,谁身高高,谁挣钱多。等等。
正是由于对象没有比较性,所以我们才在类中定义比较性,让其具有可比较性。这就是TreeSet实现排序的第一种方式。当时这种方式仅限于同类对象进行比较,例如人和人比较,但是实现不同类型的对象比较时,这种方法就不行了。
Treeset中的第二种比较方式,比较通用。我们知道,如果对象元素不具备比较性,我们可以让装它的容器具备可比较性。这就是第二种方法的出发点。
实现方法是:
定义一个类,实现Comparetor接口,覆盖compare方法。
使用时要想分清到底使用什么方法。首先看你的比较对象元素时什么类型的。一般使用第二种,即比较器
注意要记住:
Comparetor中是compare方法
而Comparable中是compareTo方法
希望能帮到你。
给一个毕老师视频中的例子:
class TreeSetDemo2
{
public static void main(String[] args)
{
TreeSet ts = new TreeSet(new MyCompare());
//使用构造器TreeSet(Comparator<? super E> comparator)
ts.add(new Student("lisi03",22));
ts.add(new Student("lisi02",20));
ts.add(new Student("lisi09",19));
ts.add(new Student("lisi01",18));
ts.add(new Student("lisi01",18));
Iterator it= ts.iterator();
while(it.hasNext())
{
Student p = (Student)it.next();
sop(p.getName()+"..."+p.getAge());
}
}
public static void sop(Object obj)
{
System.out.println(obj);
}
}
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()));
/*
if(s1.getAge()>s2.getAge())
return 1;
if(s1.getAge()==s2.getAge())
return 0;
return -1;
*/
}
return num;
}
}
class Student implements Comparable//该接口强制让学生具备可比性
{
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;
}
public int compareTo(Object obj)//覆盖的方法不能声明
{
if(!(obj instanceof Student))
throw new RuntimeException("不是学生对象");
Student s= (Student)obj;
System.out.println(this.name+"..compareto.."+s.name);
if (this.age>s.age)
return 1;
if(this.age==s.age)
{
return this.name.compareTo(s.name);
}
return -1;
}
}
复制代码
作者:
gerenvip
时间:
2013-4-15 11:52
gerenvip 发表于 2013-4-15 11:48
这个主要清楚分别用在什么地方,就很容易明白:
TreeSet我们知道可以对Set集合中的元素进行排序
而排序有两 ...
不好意思,很多错别字,将就着看哈,呵呵!
作者:
_王涛
时间:
2013-4-15 13:04
Comparator接口,在使用时,也就是所要排序的集合不具备比较性,或具备比较性,但不是我们想要的时候,就可以用子类去实现Colparator接口,并且实现compare方法,创建一个比较器。
comparable接口,是元素在不具备比较性的时候,我们可以强制让对象具备比较性,并实现compareTo方法,当前这个对象与指定对象进行顺序比较。当该对象小于、等于或大于指定对象时,分别返回一个负整数、零或者正整数。
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2