本帖最后由 刘煜 于 2012-7-11 18:10 编辑
首先你必须清楚Comparator和Comparable两个接口表面是用来比较用的,根本上是为了使集合通过比较能实现排序。当需要排序的集合或数组不是单纯的数字型时,通常可以使用Comparator或Comparable,以简单的方式实现对象排序或自定义排序。下面针对两个接口分别介绍以及在Set集合中的应用:
一、Comparator
强行对某个集合collection对象进行整体排序,可以将Comparator传递给Collections.sort或Arrays.sort。
接口方法: int compare(Object o1, Object o2);
案例:
import java.util.*;
public class SampleComparator implements Comparator<String>
{
public int compare(String o1, String o2)
{
return toInt(o1) - toInt(o2);
}
//将字符转换成对应的整数
private int toInt(String str)
{
str = str.replaceAll("一", "1");
str = str.replaceAll("二", "2");
str = str.replaceAll("三", "3");
return Integer.parseInt(str);
}
public static void main(String[] args)
{
String[] array = new String[] { "一二", "三", "二" };
Arrays.sort(array, new SampleComparator()); //按从小到大排序
for (int i = 0; i < array.length; i++)
{
System.out.println(array);
}
}
} 结果: 二 三 一二
二、Comparable
强行对集合中实现它的每个类的对象进行整体排序,实现此接口的对象列表(和数组)可以通过Collections.sort或Arrays.sort进行自动排序。
接口方法:int compareTo(Object o);
假设对象User,需要按年龄排序:
import java.util.Arrays;
public class User implements Comparable<User>
{
private String id;
private int age;
public User(String id, int age)
{
this.id = id;
this.age = age;
}
public int getAge()
{
return age;
}
public void setAge(int age)
{
this.age = age;
}
public String getId()
{
return id;
}
public void setId(String id)
{
this.id = id;
}
public int compareTo(User u)
{
return this.age - u.getAge();
}
public static void main(String[] args)
{
User[] users = new User[] { new User("a", 30), new User("b", 20) };
Arrays.sort(users);
for (int i = 0; i < users.length; i++) {
User user = users;
System.out.println(user.getId() + " " + user.getAge());
}
}
}
三、Comparator和Comparable的区别
1)先看一下使用Comparator对User集合实现排序的方式:一个类实现了Camparable接口则表明这个类的对象之间是可以相互比较的,这个类对象组成的集合就可以直接使用sort方法排序。
Comparator可以看成一种算法的实现,将算法和数据分离,Comparator也可以在下面两种环境下使用:
1、类的设计师没有考虑到比较问题而没有实现Comparable,可以通过Comparator来实现排序而不必改变对象本身
2、可以使用多种排序标准,比如升序、降序等
2)comparable是支持自比较,在集合内部定义的方法实现的排序,而Comparator是支持外部比较,是在集合外部实现的排序。 所以,如想实现排序,就需要在集合外定义Comparator接口的方法compare()或在集合内实现Comparable接口的方法compareTo()。
注意:在TreeSet和TreeMap中添加的自定义对象必须实现Comparable接口
四、Set集合的排序
集合框架中Set集合体系最重要的特点就是可以排序,有两种排序方式,分别用到了Comparable和Comparator
第一种排序方式就是集合的元素对象具备比较性,此时就需要实现具有比较性的接口Compareble接口的compareTo方法,下面是一个完整的例子:
import java.util.*;
class TreeSetDemo
{
public static void main(String[] args)
{
TreeSet ts = new TreeSet();
ts.add(new Student("zhangsan",22));
ts.add(new Student("lisi",28));
ts.add(new Student("wangwu",21));
ts.add(new Student("liu",25));
Iterator it = ts.iterator();
while(it.hasNext())
{
Student s = (Student)it.next();
System.out.println(s.getName()+"·····"+s.getAge());
}
}
public static void sop(Object obj)
{
System.out.println(obj);
}
}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+"··Compare··"+s.name);
if(this.age>s.age)
return 1;
if(this.age==s.age)
{
return this.name.compareTo(s.name); //年龄相同时,比较姓名。
}
return -1;
}
}
第二种排序方式就是让集合自身具备比较性,在集合初始化时就有了比较方式,这时需要定义比较器(实现Comparator接口,覆盖compare方法,区别Comparable接口和CompareTo方法),将比较器对象作为参数传递给TreeSet集合的构造函数。这种方式适合元素本身不具备比较性或者排序方式与元素本身的排序方式不一致的情况。完整的例子如下:
import java.util.*;
class TreeSetDemo2
{
public static void main(String[] args)
{
TreeSet ts = new TreeSet(new MyCompare());
ts.add(new Student("zhangsan",22));
ts.add(new Student("lisi",28));
ts.add(new Student("lisi",30));
ts.add(new Student("wangwu",21));
ts.add(new Student("liu",25));
ts.add(new Student("zhao",25));
Iterator it = ts.iterator();
while(it.hasNext())
{
Student s = (Student)it.next();
System.out.println(s.getName()+"·····"+s.getAge());
}
}
}
class MyCompare implements Comparator
{
public int compare(Object o1,Object o2)
{
Student s1 = (Student)o1;
Student s2 = (Student)o2;
int result = s1.getName().compareTo(s2.getName());
if(result==0)//姓名相同时,比较年龄
{
return new Integer(s1.getAge()).compareTo(new Integer(s2.getAge()));
}
return result;
}
}
希望以上的例子对你有帮助!!!
|