还不知道java8怎么对集合排序吗

127 阅读3分钟

本文已参与「新人创作礼」活动, 一起开启掘金创作之路。

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);
      }
   }
}

看下什么操作都不做直接进行排序会出现什么样的情况

微信图片_20220113223123.png

报错,说是不能被转换为java.lang.Comparable,他不知道按照什么规则来排序。

我们改下代码,想让他按照age字段来排序

List<User> collect = users.stream().sorted(Comparator.comparing(User::getAge)).collect(Collectors.toList());

微信图片_20220113223627.png 可以看到已经按照我们指定的字段来排序了,默认升序。

还可以降序排序操作

List<User> collect = users.stream().sorted(Comparator.comparing(User::getAge).reversed()).collect(Collectors.toList());

微信图片_20220113223938.png 可以看到结果已经按照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);
   }
}

微信图片_20220113223938.png 可以看到对比字段相同的情况下,使用的另外一个指定的字段来对比。

还可以使用另外一种方式,实体对象实现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());

微信图片_20220113225050.png 可以看到实现了Comparable接口,在lambda表达式中未指定字段也不会报错了。并按照compareTo方法中的实现对指定字段进行了排序

顺便再补充下java8对集合操作的一些常见的用法

map获取集合元素中指定字段的集合

List<String> collect = users.stream().map(User::getName).collect(Collectors.toList());

微信图片_20220113225510.png filter获取集合中符合条件的元素

List<User> collect = users.stream().filter(item -> item.getAge() == 19).collect(Collectors.toList());

微信图片_20220113225736.png 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);
});

微信图片_20220113230141.png 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);
});

微信图片_20220113230440.png