您的位置:首页 > 编程语言 > Java开发

深入理解Java集合框架系列-第三章 使用集合排序

2017-08-03 16:01 393 查看
3.1 使用TreeMap排序
   在TreeMap中,默认为自然排序,也可以指定比较器,按照比较器的算法排序。实例如下:
   import java.util.Comparator;
import java.util.Map;
import java.util.TreeMap;
public class TreeMapDemo {
      public static void main(String[] args) {
       /**
     * 自然排序  
     */
 Map<String,String> maps=new TreeMap<String,String>();
 maps.put("12", "12");
 maps.put("1", "1");
 maps.put("3", "3");
 maps.put("10", "10");
 System.out.println("TreeMap默认为自然排序:");
 for(String i:maps.keySet()){
 System.out.println("key="+i+" value="+maps.get(i));
 
 }
 /**
  * 定义一个比较器
  */
 Comparator<String> c=new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
 int a=  Integer.valueOf(o1);
 int b=Integer.valueOf(o2);
 if(a==b)
return 0;
 else
 return a-b;
}
};
 System.out.println("TreeMap指定比较器:");
 /**
  * 在构造器中指定比较器对象
  */
      Map<String,String> maps2=new TreeMap<String,String>(c);
 maps2.put("12", "12");
 maps2.put("1", "1");
 maps2.put("3", "3");
 maps2.put("23", "23");
 for(String s:maps2.keySet()){
 System.out.println("key="+s+" value="+maps2.get(s));

 }
}
}
3.2 使用TreeSet排序
1.排序的引入
由于TreeSet可以实现对元素按照某种规则进行排序,例如下面的例子
package cn.com.bochy;

import java.util.TreeSet;

public class TreeSetDemo {

public static void main(String[]
args) {

// 自然顺序进行排序

TreeSet<Integer> ts = new TreeSet<Integer>();

// 创建元素并添加

ts.add(10);

ts.add(28);

ts.add(253);

ts.add(212);

ts.add(17);

//遍历

for (Integer i : ts) {

System.out.print(i+" ");

}

}

}
运行结果为:
10 17 28 212 253

但是对自定义对象呢?
package cn.com.bochy;

public class Stu {

   private int age;

   public int getAge() {

return age;

}

public void setAge(int age)
{

this.age = age;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

private String
name;

public Stu() {

// TODO Auto-generated constructor stub

}

public Stu(int age, String name) {

super();

this.age = age;

this.name = name;

}

}
package cn.com.bochy;

import java.util.TreeSet;

public class TreeSetDemo {

public static void main(String[]
args) {

TreeSet<Stu> ts=new TreeSet<Stu>();

//创建元素对象

Stu s1=new Stu("zhangsan",20);

Stu s2=new Stu("lis",22);

Stu  s3=new Stu("wangwu",24);

Stu  s4=new Stu("chenliu",26);

Stu  s5=new Stu("zhangsan",22);

Stu  s6=new Stu("qianqi",24);

//将元素对象添加到集合对象中

ts.add(s1);

ts.add(s2);

ts.add(s3);

ts.add(s4);

ts.add(s5);

ts.add(s6);

//遍历

for(Stu s:ts){

System.out.println(s.getName()+"-----------"+s.getAge());

}

}

}
 
运行结果:
Exception in thread "main"
java.lang.ClassCastException: cn.com.bochy.Stu cannot be cast to java.lang.Comparable
原因分析:
由于不知道该安照那一中排序方式排序,所以会报错。
解决方法1:
1.Stu类中实现 Comparable<T>接口
2.重写Comparable接口中的Compareto方法
排序法则:按照年龄大小排序,如果年龄相同,则按照姓名的先后顺序排序
package cn.com.bochy;

public class Stu  implements Comparable<Stu>{

   private int age;

   public int getAge() {

return age;

}

public void setAge(int age)
{

this.age = age;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

private String
name;

public Stu() {

// TODO Auto-generated constructor stub

}

public Stu(String name,int age) {

super();

this.age = age;

this.name = name;

}

 

@Override

public int compareTo(Stu o) {

 if(this.getAge()>o.getAge()){

   return 1;

   }

   if(this.getAge()<o.getAge()){

   return -1;

   }

   if(this.getAge()==o.getAge()){

   return (this.getName().compareTo(o.getName()));

   }

   return 0;

}

}
package cn.com.bochy;

import java.util.TreeSet;

public class TreeSetDemo {

public static void main(String[]
args) {

TreeSet<Stu> ts=new TreeSet<Stu>();

//创建元素对象

Stu s1=new Stu("azhangsan",20);

Stu s2=new Stu("blis",22);

Stu  s3=new Stu("wangwu",24);

Stu  s4=new Stu("chenliu",26);

Stu  s5=new Stu("alisi",22);

Stu  s6=new Stu("qianqi",24);

//将元素对象添加到集合对象中

ts.add(s1);

ts.add(s2);

ts.add(s3);

ts.add(s4);

ts.add(s5);

ts.add(s6);

//遍历

for(Stu s:ts){

System.out.println(s.getName()+"-----------"+s.getAge());

}

}

}
执行结果:
azhangsan-----------20

alisi-----------22

blis-----------22

qianqi-----------24

wangwu-----------24

chenliu-----------26
解决方法2:
1.单独创建一个比较类,并且要让其继承Comparator<T>接口
2.重写Comparator接口中的Compare方法
3.在声明TreeSet对象时,指定比较对象。
需要注意的是,由于有了一个比较器,不要在Stu类中再实现omparable<T>接口。
声明一个比较器:
package cn.com.bochy;

import java.util.Comparator;

public class StuComPare
implements Comparator<Stu> {

@Override

public int compare(Stu o1, Stu o2) {

 if(o1.getAge()>o2.getAge()){

   return 1;

   }

   if(o1.getAge()<o2.getAge()){

   return -1;

   }

   if(o1.getAge()==o2.getAge()){

   return (o1.getName().compareTo(o2.getName()));

   }

   return 0;

}

}
package cn.com.bochy;

import java.util.TreeSet;

public class TreeSetDemo {

public static void main(String[]
args) {

TreeSet<Stu> ts=new TreeSet<Stu>(new StuComPare());

//创建元素对象

Stu s1=new Stu("azhangsan",20);

Stu s2=new Stu("blis",22);

Stu  s3=new Stu("wangwu",24);

Stu  s4=new Stu("chenliu",26);

Stu  s5=new Stu("alisi",22);

Stu  s6=new Stu("qianqi",24);

//将元素对象添加到集合对象中

ts.add(s1);

ts.add(s2);

ts.add(s3);

ts.add(s4);

ts.add(s5);

ts.add(s6);

//遍历

for(Stu s:ts){

System.out.println(s.getName()+"-----------"+s.getAge());

}

}

}
由于单独创建一个类不是特别好,因而可以将StuComPare的内容直接写到主类中
package cn.com.bochy;

import java.util.Comparator;

import java.util.TreeSet;

public class TreeSetDemo {

public static void main(String[]
args) {

TreeSet<Stu> ts=new TreeSet<Stu>(new Comparator<Stu>(){

@Override

public int compare(Stu o1, Stu o2) {

 if(o1.getAge()>o2.getAge()){

   return 1;

   }

   if(o1.getAge()<o2.getAge()){

   return -1;

   }

   if(o1.getAge()==o2.getAge()){

   return (o1.getName().compareTo(o2.getName()));

   }

   return 0;

}});

//创建元素对象

Stu s1=new Stu("azhangsan",20);

Stu s2=new Stu("blis",22);

Stu  s3=new Stu("wangwu",24);

Stu  s4=new Stu("chenliu",26);

Stu  s5=new Stu("alisi",22);

Stu  s6=new Stu("qianqi",24);

//将元素对象添加到集合对象中

ts.add(s1);

ts.add(s2);

ts.add(s3);

ts.add(s4);

ts.add(s5);

ts.add(s6);

//遍历

for(Stu s:ts){

System.out.println(s.getName()+"-----------"+s.getAge());

}

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐