最近经常会用到集合排序,现在总结一下,方便以后复用。
首先理解内部排序和外部排序。
- 内部排序是在原来的集合上进行的操作,无需新对象接收。
- 外部排序对原来的集合不进行操作,生成一个新的排序好的对象。
一、集合内的元素是Integer,String等Java的原生类型
1.内部排序
List<Integer> integers = Lists.newArrayList(5, 2, 6, 1, 8, 3, 9, 4);
List<String> strings = Lists.newArrayList("1", "15", "20", "11", "10", "55");
Collections.sort(integers);
Collections.sort(strings);
System.out.println(integers);
System.out.println(strings);
//打印结果
[1, 2, 3, 4, 5, 6, 8, 9]
[1, 10, 11, 15, 20, 55]
// 默认升序,如需降序可以这样写
Collections.sort(integers,Collections.reverseOrder());
// 这样也可以,不过这个Comparator.reverseOrder()底层还是调用的上面那个方法
Collections.sort(integers,Comparator.reverseOrder());
//如果你的jdk版本在1.8以上了可以直接用以下方式
integers.sort(Comparator.naturalOrder());
strings.sort(Comparator.naturalOrder());
//打印结果默认升序,降序使用以下方式
integers.sort(Comparator.reverseOrder());
strings.sort(Comparator.reverseOrder());
Collection.sort()方法是一个内部排序的方法,我对内部排序的理解就是,在原来的对象上面进行排序,与外部排序不同的是不需要一个新的对象进行接收。这个方法排序的集合的内部元素需要实现Comparable接口。
2.外部排序
List<Integer> integers = Lists.newArrayList(5, 2, 6, 1, 8, 3, 9, 4);
List<String> strings = Lists.newArrayList("1", "15", "20", "11", "10", "55");
List<Integer> a1 = integers.stream().sorted().collect(Collectors.toList());
List<String> a2 = strings.stream().sorted().collect(Collectors.toList());
System.out.println(a1 );
System.out.println(a2);
//打印结果
[1, 2, 3, 4, 5, 6, 8, 9]
[1, 10, 11, 15, 20, 55]
// 默认升序,如需降序可以这样写
List<Integer> a1 = integers.stream().sorted(Comparator.reverseOrder()).collect(Collectors.toList());
采用的是Java8中的StreamApi,流的方式,是一种外部排序,需要对象来接收,很灵活方便,sorted方法中可以自己返回一个自定义的Comparator比较器进行自定义排序。排序只是StreamApi的冰山一角。
二、集合内的元素是自定义类型
public class User { //简单的User类
private String name;
private Integer age;
public User(String name, Integer age) {
this.name = name;
this.age = age;
}
}
1.内部排序
List<User> users = Lists.newArrayList(
new User("张三", 16)
, new User("李四", 21)
, new User("王五", 15)
, new User("赵六", 14));
users.sort(Comparator.comparing(User::getAge));
//打印结果
name=赵六, age=14
name=王五, age=15
name=张三, age=16
name=李四, age=21
//默认升序,降序使用以下方式
users.sort(Comparator.comparing(User::getAge).reversed());
//上面这种方式不好理解的话,下面这种方式就是上面那种方式的解读。
users.sort(new Comparator<User>() {
@Override
public int compare(User o1, User o2) {
if (o1.getAge()> o2.getAge()){
return 1;
}
if (o1.getAge()==o2.getAge()){
return 0;
}
return -1;
}
});
2.外部排序
List<User> users = Lists.newArrayList(
new User("张三", 16)
, new User("李四", 21)
, new User("王五", 15)
, new User("赵六", 14));
List<User> collect = users.stream()
.sorted(Comparator.comparing(User::getAge))
.collect(Collectors.toList());
//打印结果
name=赵六, age=14
name=王五, age=15
name=张三, age=16
name=李四, age=21
//默认升序降序可以使用以下方式
List<User> collect = users.stream()
.sorted(Comparator.comparing(User::getAge).reversed())
.collect(Collectors.toList());
总结
根据自己的需求选择内排和外排,注意内排会影响原集合中的元素顺序。排序的方式应该还有,但这些已经够用了。简单的排序使用集合自带的sort()方法足以,如果有逻辑的进行排序还是建议使用StreamApi,他不止能排序,去学习一下会发现很多惊喜。