本文已参与「新人创作礼」活动, 一起开启掘金创作之路。
java8操作集合排序
在我们的日常工作当中操作集合是一件很常见的事情,java8更是对集合操作带来了很大的便利。今天来讲下java8中怎样来按照自己想要的规则对集合进行排序以及java8中对集合操作的一些常见用法。
先把数据初始化好
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class User {
private Long id;
private String name;
private Integer age;
private LocalDateTime createTime;
public static void main(String[] args) {
User user = new User(1L, "张一", 19, LocalDateTime.parse("2022-01-13 22:10:00", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
User user1 = new User(2L, "张二", 21, LocalDateTime.parse("2022-01-13 22:01:00", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
User user2 = new User(3L, "张三", 17, LocalDateTime.parse("2022-01-13 21:00:00", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
User user3 = new User(4L, "张四", 30, LocalDateTime.parse("2022-01-13 23:00:00", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
User user4 = new User(5L, "张五", 20, LocalDateTime.parse("2022-01-13 20:00:00", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
List<User> users = new ArrayList<>();
users.add(user);
users.add(user1);
users.add(user2);
users.add(user3);
users.add(user4);
List<User> collect = users.stream().sorted().collect(Collectors.toList());
for (User u : collect) {
System.out.println(u);
}
}
}
看下什么操作都不做直接进行排序会出现什么样的情况
报错,说是不能被转换为java.lang.Comparable,他不知道按照什么规则来排序。
我们改下代码,想让他按照age字段来排序
List<User> collect = users.stream().sorted(Comparator.comparing(User::getAge)).collect(Collectors.toList());
可以看到已经按照我们指定的字段来排序了,默认升序。
还可以降序排序操作
List<User> collect = users.stream().sorted(Comparator.comparing(User::getAge).reversed()).collect(Collectors.toList());
可以看到结果已经按照age字段的降序来排列。其他字段也是一样。
如遇到字段结果相同的情况,还可以再找一个字段来进行排序
public static void main(String[] args) {
User user = new User(1L, "张一", 19, LocalDateTime.parse("2022-01-13 22:10:00", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
User user1 = new User(2L, "张二", 19, LocalDateTime.parse("2022-01-13 22:01:00", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
User user2 = new User(3L, "张三", 17, LocalDateTime.parse("2022-01-13 21:00:00", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
User user3 = new User(4L, "张四", 30, LocalDateTime.parse("2022-01-13 23:00:00", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
User user4 = new User(5L, "张五", 20, LocalDateTime.parse("2022-01-13 20:00:00", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
List<User> users = new ArrayList<>();
users.add(user);
users.add(user1);
users.add(user2);
users.add(user3);
users.add(user4);
List<User> collect = users.stream().sorted(Comparator.comparing(User::getCreateTime).thenComparing(User::getCreateTime)).collect(Collectors.toList());
for (User u : collect) {
System.out.println(u);
}
}
可以看到对比字段相同的情况下,使用的另外一个指定的字段来对比。
还可以使用另外一种方式,实体对象实现Comparable接口中的compareTo方法
public class User implements Comparable<User>{
private Long id;
private String name;
private Integer age;
private LocalDateTime createTime;
@Override
public int compareTo(User user) {
if (this.createTime.isAfter(user.createTime)) {
return 1;
} else if(this.createTime.isBefore(user.createTime)) {
return -1;
}
return 0;
}
List<User> collect = users.stream().sorted().collect(Collectors.toList());
可以看到实现了Comparable接口,在lambda表达式中未指定字段也不会报错了。并按照compareTo方法中的实现对指定字段进行了排序
顺便再补充下java8对集合操作的一些常见的用法
map获取集合元素中指定字段的集合
List<String> collect = users.stream().map(User::getName).collect(Collectors.toList());
filter获取集合中符合条件的元素
List<User> collect = users.stream().filter(item -> item.getAge() == 19).collect(Collectors.toList());
Collectors.toMap集合转Map可以指定Map的key和value为哪个字段
Map<Long, User> collect = users.stream().collect(Collectors.toMap(User::getId, Function.identity()));
collect.forEach((id, item)->{
System.out.println("id:"+id+" item:"+item);
});
Collectors.groupingBy按某个字段对集合进行分组
Map<Integer, List<User>> collect = users.stream().collect(Collectors.groupingBy(User::getAge));
collect.forEach((id, item)->{
System.out.println("id:"+id+" item:"+item);
});