按对象某属性排序的几种方法:
第一种,可以实现边添加边排序,需要用到TreeSet。
第二种,用数组存放对象们,但是不需单独取出某属性排列好再重存,而是在原数组上用比较器重新排一次序。需要用到Arrays.sort(arr,comparator)。
第三种,用集合类中的list的子类存放对象们,然后排序。需要用到Collections.sort(list,comparator)。
一、TreeSet
创建:
序号 | 构造函数的说明 |
---|---|
1 | TreeSet ()
此构造函数构造空树集,将在根据其元素的自然顺序按升序排序。 |
2 | TreeSet (集合 c)
此构造函数生成树的集合,它包含的元素的集合 c。 |
3 | TreeSet (比较器 comp)
此构造函数构造一个空树集,将根据给定的比较器进行排序。 |
增:
boolean |
add(E e)
将指定的元素添加到这套,如果它已不存在。
|
boolean |
addAll(Collection<? extends E> c)
在加入这一组指定的集合中添加的所有元素。
|
删:
boolean |
remove(Object o)
从这一组中移除指定的元素,如果它存在。
|
void |
clear()
从这一组中移除所有元素。
|
查:
Comparator<? super E> |
comparator()
返回用于排序在这集,或空元素,如果这套使用自然排序其元素的比较。
|
boolean |
contains(Object o)
如果此集合包含指定的元素,则返回
true 。 |
boolean |
isEmpty()
如果此集不包含任何元素,则返回
true 。 |
Iterator<E> |
iterator()
返回迭代器中这套以升序排序的元素。
|
|
|
int |
size()
在这套 (其基数) 中返回的元素的数目。
|
|
遍历:通过迭代器遍历。
Iterator it=treeset.iterator();
while(it.hasNext()){
//操作当前结点。
}
代码实现:
TreeSet是一个有序集合,TreeSet中的元素将按照升序排列。
TreeSet存储对象的时候, 可以排序, 其中Integer有默认排序方法, String有默认排序方法,,而自定义的类对象存储的时候则没有顺序,需要自定义排序算法。
如果想把自定义类的对象存入TreeSet进行排序,或者对int,String对象想定义自己的排序方法,有以下两种方法:
排序的第一种方式:
让元素自身具备比较性。让元素实现Comparable接口,覆盖compareTo方法,在方法内定义比较算法,
根据大小关系, 返回正数负数或零。在使用TreeSet存储对象的时候, add()方法内部就会自动调用compareTo()方法进行比较,
根据比较结果使用二叉树形式进行存储。
排序的第二种方式:
自定义比较器。 定义一个类实现Comparator接口,覆盖compare方法。将该Comparator接口子类对象传递给TreeSet集合构造函数。
第一种:类定义时实现Comparable接口,定义自身的比较算法。
此处以Person类为例,把人名和年龄作为对象属性,存放进treeset中,按照年龄的升/降序保存。
此处以Person类为例,把人名和年龄作为对象属性,存放进treeset中,按照年龄的升/降序保存。
1 public class TreeSetTest { 2 3 public static void main(String[] args) { 4 TreeSet people=new TreeSet(); 5 people.add(new Person("小明", 20)); 6 people.add(new Person("小张", 30)); 7 people.add(new Person("小刘", 18)); 8 people.add(new Person("小林", 17)); 9 people.add(new Person("小刘", 35)); 10 11 Iterator it=people.iterator(); 12 while(it.hasNext()){ 13 System.out.println(it.next()); 14 } 15 } 16 17 } 18 class Person implements Comparable{ //定义类时,实现比较接口 19 20 String name; 21 int age; 22 23 public Person() { 24 } 25 26 public Person(String name, int age) { 27 this.name = name; 28 this.age = age; 29 } 30 31 public String toString(){ 32 return "姓名:"+name+",年龄:"+age; 33 } 34 /* 35 compareTo(Object o):参数是从根节点开始依次传进来的结点,直到确定合适的位置用来安插新节点。 36 方法返回三个值,分别对应三种动作:返回1,则继续递进,把新结点与下一层的结点进行比较; 37 返回0,则该属性值不足以决定两结点位置区别,再定义其他属性的比较算法来进一步比较两对象; 38 返回-1,则新结点优先级大于当前层,往上一层比较; 39 */ 40 public int compareTo(Object o) { 41 Person curr=(Person) o; 42 //int result = this.age<curr.age?1:(this.age==curr.age?0:-1);//降序排列:新插入结点与当前比较层结点的属性比较,小则返回1,继续往下一层比较 43 int result = this.age>curr.age?1:(this.age==curr.age?0:-1);//升序排列:新插入结点与当前比较层结点的属性比较,大则返回1,继续往下一层比较 44 if(result==0){ 45 result=this.name.compareTo(curr.name);//age相同时,则以姓名的字母序来排列。前面说过,int、string类型是有默认排列算法的,所以此处直接用 46 } 47 return result; 48 } 49 }
第二种:定义Comparator接口的实现类(比较器),在类中定义对象的比较算法。在创建Treeset时把比较器对象传进去。
1 public class TreeSetTest { 2 3 /** 4 * @param args the command line arguments 5 */ 6 public static void main(String[] args) { 7 TreeSet people=new TreeSet(new MyComparator());//把比较器对象作为TreeSet的构造函数参数 8 people.add(new Person("小明", 20)); 9 people.add(new Person("小张", 30)); 10 people.add(new Person("小刘", 18)); 11 people.add(new Person("小林", 17)); 12 people.add(new Person("小刘", 35)); 13 14 Iterator it=people.iterator();//用迭代器遍历treeset 15 while(it.hasNext()){ 16 System.out.println(it.next()); 17 } 18 } 19 20 } 21 class Person { 22 23 String name; 24 int age; 25 26 public Person() { 27 } 28 29 public Person(String name, int age) { 30 this.name = name; 31 this.age = age; 32 } 33 34 public String toString(){ 35 return "姓名:"+name+",年龄:"+age; 36 } 37 38 } 39 class MyComparator implements Comparator{//实现Comparator接口,自定义比较器,实现compare方法定义比较算法 40 41 /* 42 compare(o1,o2):参数o1是待插入的结点,o2是从树根节点逐层遍历下来的结点,用于当前比较。 43 方法返回三个值,分别对应三种动作:返回1,则继续递进,把新结点与下一层的结点进行比较; 44 返回0,则该属性值不足以决定两结点位置区别,再定义其他属性的比较算法来进一步比较两对象; 45 返回-1,则新结点优先级大于当前层,往上一层比较; 46 47 */ 48 public int compare(Object o1, Object o2) { 49 Person p1=(Person)o1; 50 Person p2=(Person)o2; 51 52 int result=p1.age<p2.age?1:(p1.age==p2.age?0:-1);//降序排列 53 //int result=p1.age<p2.age?1:(p1.age==p2.age?0:-1);//升序排列 54 55 if(result==0){ 56 result=p1.name.compareTo(p2.name); 57 } 58 return result; 59 } 60 61 }
二、用数组存放对象,用比较器改变sort()排序方法
数组本身有默认的排序方法,针对int、string等基本类型有默认的sort()方法。而针对类对象的排序,可以给sort()方法传进一个比较器对象,赋予其排序的算法。
1 public class ArraysTest { 2 3 public static void main(String[] args) { 4 5 Person[] people=new Person[5]; 6 people[0]=(new Person("小明", 20)); 7 people[1]=(new Person("小张", 30)); 8 people[2]=(new Person("小刘", 18)); 9 people[3]=(new Person("小林", 17)); 10 people[4]=(new Person("小刘", 35)); 11 12 Arrays.sort(people,new MyCompare());//传进来一个比较器对象,使数组按比较器定义的规则来排序 13 for(Person i:people){ 14 System.out.println(i); 15 } 16 17 } 18 19 } 20 class Person { 21 22 23 24 String name; 25 int age; 26 27 28 29 public Person() { 30 } 31 32 33 34 public Person(String name, int age) { 35 this.name = name; 36 this.age = age; 37 } 38 39 public String toString(){ 40 return "姓名:"+name+",年龄:"+age; 41 } 42 43 } 44 45 46 47 class MyCompare implements Comparator<Person>{//定义比较器 48 49 50 51 /* 52 53 重写比较方法compare(o1,o2): 54 55 方法传进来两个对象,用两个对象的某属性进行对比,返回一个int。 56 57 int>0,则o1排在o2后面; 58 59 int<0,则o1排在o2前面; 60 61 int=0,则维持原相对位置,即原来存放时o1、o2的前后地址顺序。 62 63 */ 64 public int compare(Person o1, Person o2) { 65 int result; 66 if(o1.age>o2.age){ 67 result=1; 68 } 69 else if(o1.age<o2.age){ 70 result=-1; 71 } 72 else{ 73 result=0; 74 } 75 return result; 76 } 77 78 }
第三种:用list的子类:Vector、ArrayList存放对象们,调用Collections.sort(list,comparator)方法进行排序。
1 public class CollectionsTest { 2 3 public static void main(String[] args) { 4 Vector<Person> people=new Vector<>();//用向量保存对象 5 6 //ArrayList<Person> people=new ArrayList<>()://用ArrayList保存对象。 7 people.add(new Person("小明", 20)); 8 people.add(new Person("小张", 30)); 9 people.add(new Person("小刘", 18)); 10 people.add(new Person("小林", 17)); 11 people.add(new Person("小刘", 35)); 12 Collections.sort(people,new MyComparator());//调用方法进行排序 13 Iterator it=people.iterator(); 14 while(it.hasNext()){ 15 System.out.println(it.next()); 16 } 17 } 18 19 } 20 class Person { 21 22 String name; 23 int age; 24 25 public Person() { 26 } 27 28 public Person(String name, int age) { 29 this.name = name; 30 this.age = age; 31 } 32 33 public String toString(){ 34 return "姓名:"+name+",年龄:"+age; 35 } 36 37 } 38 class MyComparator implements Comparator<Person>{//实现Comparator接口,自定义比较器,实现compare方法定义比较算法 39 40 /* 41 compare(o1,o2):方法传进两个对象,根据某属性进行比较,返回一个int值。 42 int>0,o1排在o2后; 43 int<0,o1排在o2前; 44 int=0,维持原来存放时的相对位置。 45 46 */ 47 public int compare(Person p1, Person p2) { 48 int result=p1.age<p2.age?1:(p1.age==p2.age?0:-1);//降序排列 49 //int result=p1.age<p2.age?1:(p1.age==p2.age?0:-1);//升序排列 50 51 if(result==0){ 52 result=p1.name.compareTo(p2.name); 53 } 54 return result; 55 } 56 57 }