一、背景
1.软件开发过程中集合排序是比较强大的功能,会使用集合Map、Set、List实现排序功能,知道匿名内部类Comparator很关键,搞清楚集合排序的性能开销,排序遇到的坑以及解决的方法,注意下面的例子都是JDK1.8的用法。
二、Set集合排序
1.UML类图
三、注意点
1.我们先来说下集合的各个特点:
2.List的主要特点以及用法
2.1.可以允许存储重复的对象.
2.2.可以插入多个null元素.
2.3.是一个有序容器,保持了每一个元素的插入顺序,插入的顺序即输出的顺序.
2.5.常用的实现类有 ArrayList、LinkedList 和 Vector。ArrayList 最为流行,它提供了使用索引的随意访问,而 LinkedList 则对于经常需要从 List 中添加或删除元素的场合更为合适.
3.Set集合的主要特点及用法
3.1 不允许重复对象
3.2 只允许一个 null 元素
3.3 无序容器,你无法保证每个元素的存储顺序,TreeSet通过 Comparator 或者 Comparable 维护了一个排序顺序
3.4 Set 接口最流行的几个实现类是 HashSet、LinkedHashSet 以及 TreeSet。最流行的是基于 HashMap 实现的 HashSet;TreeSet 还实现了 SortedSet 接口,因此 TreeSet 是一个根据其 compare() 和 compareTo() 的定义进行排序的有序容器
4.Map集合的主要特点及用法
4.1 Map不是collection的子接口或者实现类。Map是一个接口。而List和Set是collection的子接口
4.2 Map 的 每个 Entry 都持有两个对象,也就是一个键一个值,Map 可能会持有相同的值对象但键对象必须是唯一的,这是双列集合的特点
4.3 TreeMap 也通过 Comparator 或者 Comparable 维护了一个排序顺序
4.4 Map 里你可以拥有随意个 null 值但最多只能有一个 null 键
4.5 Map 接口最流行的几个实现类是 HashMap、LinkedHashMap、Hashtable 和 TreeMap。(其中HashMap、TreeMap最常用)
5. 区别
5.1、Collection 和 Map 的区别
容器内每个为之所存储的元素个数不同。
Collection类型者,每个位置只有一个元素。
Map类型者,持有 key-value pair,像个小型数据库。
5.2、各自旗下的子类关系
Collection
–List:将以特定次序存储元素。所以取出来的顺序可能和放入顺序不同。
–ArrayList / LinkedList / Vector
–Set : 不能含有重复的元素
–HashSet / TreeSet
Map
–HashMap
–HashTable
–TreeMap
四、第一种做法(排序)
1.实体类
public class Person{
private String id;
private String name;
private String address;
public Person(String id, String name, String address) {
this.id = id;
this.name = name;
this.address = address;
}
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 String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "Person{" +
"id='" + id + '\'' +
", name='" + name + '\'' +
", address='" + address + '\'' +
'}';
}
}
2.测试类
public class TreeSetTest {
public static void main(String[] args) {
Set set = new TreeSet(new Comparator() {
@Override
public int compare(Person o1, Person o2) {
return new Double(o1.getId()).compareTo(new Double(o2.getId()));//升序排列
}
});
//产生100以内的随机数
int num = (int)(Math.random()*100+1);
for(int i=num;i>0;i--){
set.add(new Person(""+i,"张三","河南"));
}
for(Object o : set){
System.out.println(o);
}
}
}
3.结果(升序)
Person{id='1', name='张三', address='河南'}
Person{id='2', name='张三', address='河南'}
Person{id='3', name='张三', address='河南'}
Person{id='4', name='张三', address='河南'}
Person{id='5', name='张三', address='河南'}
Person{id='6', name='张三', address='河南'}
Person{id='7', name='张三', address='河南'}
Person{id='8', name='张三', address='河南'}
Person{id='9', name='张三', address='河南'}
Person{id='10', name='张三', address='河南'}
Person{id='11', name='张三', address='河南'}
4.如果要倒序(改动一下面这个就行了)
Set set = new TreeSet(new Comparator() {
@Override
public int compare(Person o1, Person o2) {
return new Double(o2.getId()).compareTo(new Double(o1.getId()));//降序排列
}
});
五、第二种做法
1.实体类
public class Person implements Comparable {
private String id;
private String name;
private String address;
public Person(String id, String name, String address) {
this.id = id;
this.name = name;
this.address = address;
}
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 String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "Person{" +
"id='" + id + '\'' +
", name='" + name + '\'' +
", address='" + address + '\'' +
'}';
}
@Override
public int compareTo(Person o) {
if (o instanceof Person) {
Person o1 = (Person) o;
return new Double(o1.getId()).compareTo(new Double(this.getId()));
}
throw new ClassCastException("不能转换为Person类型的对象...");
}
}
2.测试类
public class TreeSetTest {
public static void main(String[] args) {
Set set = new TreeSet();
//产生100以内的随机数
int num = (int)(Math.random()*100+1);
for(int i=num;i>0;i--){
set.add(new Person(""+i,"张三","河南"));
}
for(Object o : set){
System.out.println(o);
}
}
}
3.结果(倒列),正序需调换下实体类中的比较对象的位置
Person{id='10', name='张三', address='河南'}
Person{id='9', name='张三', address='河南'}
Person{id='8', name='张三', address='河南'}
Person{id='7', name='张三', address='河南'}
Person{id='6', name='张三', address='河南'}
Person{id='5', name='张三', address='河南'}
Person{id='4', name='张三', address='河南'}
Person{id='3', name='张三', address='河南'}
Person{id='2', name='张三', address='河南'}
Person{id='1', name='张三', address='河南'}
六、结束
上面是对set集合中的TreeSet排序进行的总结。
Always keep the faith!!!