集合排序---方法1:
java.lang.Comparable接口适用于一个类有自然顺序的时候。假定对象集合是同一类型,该接口允许把集合排序成自然顺序。
该接口中的int compareTo( T obj )方法: 比较当前实例对象与对象obj,如果位于对象obj之前,返回负值;如果两个对象在排序中位置相同,则返回0;如果位于对象obj后面,则返回正值。
该排序方法的实现要点:
让被放置到容器的对象类实现Comparable接口。由其中所实现的方法compareTo( )决定对象之间的排列顺序。
代码示例:
以TreeSet集合为例,让集合中的String对象与Employee对象按指定规则进行排序。
public class TreeSetDemo {
public static void main(String[] args) {
//因为TreeSet是排序的,而排序就要用到被排序元素的排序方法(compare to)
//--Comparable接口中的抽象方法,因此使用TreeSet,那么加入他当中的元素必须实现该接口
TreeSet set=new TreeSet();//空参构造,用的是默认构造方法,所以加入该集合的元素不用实现Compare to方法
//HashSet set=new HashSet();//因为这个集合不排序,因此加入这个集合元素不用实现Compare to方法
set.add("aaa");
set.add("bbb");
set.add(new Employee("张三",22));
//set.add("ccc");//不行,因为String类中的compareTo(obj)方法中把所有obj都强转成String来比较了。此处obj是Employee对象,
//因此出现ClassCastException异常
set.add(new Employee("Lili",12));
//※TreeSet调用add()方法时,会让新添加的元素调用compareTo(obj)方法,依次把已有的元素作为参数传入,进行决定大小
//由上一句,决定放在TreeXXX集合当中的元素要实现Comparable接口
//obj.compareTo(obj2) :
Iterator it=set.iterator();
while(it.hasNext()){
Object obj=it.next();
System.out.println(obj);
}
}
}
Employee对象实现Comparable接口:
public class Employee implements Comparable {
private String id;
private String name;
private int age;
public Employee(String name, int age) {
super();
this.name = name;
this.age = age;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
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;
}
@Override
public String toString() {
return "Employee [name=" + name + ", age=" + age + "]";
}
// @Override
// public int compareTo(Object o) {
//
// //return 0;//默认是0,运行结果是没有任何输出
// return 1;//按照添加的顺序输出
// //return -1;//按照添加的倒序输出
// }
//自定义排序
@Override
public int compareTo(Object o) {
if(o instanceof Employee){
Employee e=(Employee) o;
if(this.age!=e.age){
return this.age-e.age;//按年龄,顺序排序
}else{
return this.id.compareTo(e.id);
}
}
if(o instanceof String){
return 1;//按添加顺序排
}
return 0;//相等,则不能加进同一个排序集合(TreeXXX)。表示跟其他数据类型的元素无法共存于同一个集合
}
}
集合排序
-
方法
2
java.util.Comparator接口适用于一个类有自然顺序的时候。假定对象集合是同一类型,该接口允许把集合排序成自然顺序。
该接口中的compare ( T o1, To2)方法: 比较用来排序的两个参数。根据第一个参数小于、等于或大于第二个参数分别返回负、零或正整数
该排序方法的实现要点:让容器在构造时加入比较器对象。
代码示例
以TreeMap集合为例,让其中的学生按学号排列。
public class Sort2Demo {
public static void main(String[] args) {
Comparator comparator=new MyCmp();
TreeMap map=new TreeMap(comparator);
map.put("1001","Coco");
map.put("1002","Joe");
map.put("1003","Sara");
map.put("1004","Lili");
Set entries=map.entrySet();
Iterator it=entries.iterator();
while(it.hasNext()){
Map.Entry entry=(Map.Entry) it.next();
System.out.println("key="+entry.getKey()+",values="+entry.getValue());
}
}
}
MyCmp实现compare to方法
public class MyCmp implements Comparator {
@Override
public int compare(Object o1, Object o2) {
int x=o1.toString().compareTo(o2.toString());
return x;
}
}
Employee:
public class Employee {
private String id;
private String name;
private int age;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
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 Employee(String name, int age,String department) {
super();
this.name = name;
this.age = age;
}
public Employee(String name,int age){
this(name,age,"null");
}
@Override
public String toString() {
return "Employee [name=" + name + ", age=" + age + "]";
}
}
中文排序问题
比较函数对于英文字母与数字等ASCII码中的字符排序都没问题,但中文排序则明显不正确。这主要是Java中使用中文编码GB2312或GBK时,char型转换成int型的过程出现了比较大的偏差。这偏差是由compare方法导致的,因此我们可以
自己实现
Comparator
接口
。另外,国际化问题可用
Collator
类
来解决。
java.text.
Collator
类,提供以
与自然语言无关的方式
来处理文本、日期、数字和消息的类和接口。
public class SortDemo3 {
@SuppressWarnings({ "rawtypes", "unchecked" })
public static void main(String[] args) {
Comparator comparator2=new MyCmp2();
TreeMap map=new TreeMap(comparator2);
map.put("张磊","1001");
map.put("李志", "1002");
map.put("赵雷", "1003");
map.put("顾城", "1004");
Set entries=map.entrySet();
Iterator it=entries.iterator();
while(it.hasNext()){
Map.Entry entry=(Map.Entry)it.next();
System.out.println("key="+entry.getKey()+",value="+entry.getValue());
}
}
}
自己实现Comparator接口,用get collectionKey(将该 String 转换为一系列可以和其他 CollationKey 按位进行比较的位)来比较
public class MyCmp2 implements Comparator {
@Override
public int compare(Object o1, Object o2) {
Collator collator=Collator.getInstance();
CollationKey key1=collator.getCollationKey(o1.toString());
CollationKey key2=collator.getCollationKey(o2.toString());
return key1.compareTo(key2);
}
}