> 文档中心 > 【经验分享】Java 8 Stream API使用示例

【经验分享】Java 8 Stream API使用示例

文章目录

  • 前言
  • 创建一个流
  • 过滤
  • map转换
  • flatMap 先展开再转换
  • distinct 去重
  • sort 排序
  • limit+skip 可实现分页
  • peek 用于执行结果前后查看,方便调试
  • collect 收集,是流的一种终止操作
  • grouping 分组
  • partitioning 分区
  • reduce 使用累计函数进行归约

前言

Stream流式操作,针对集合、数组、函数、I/O流等提供了映射、转换、过滤、排序、聚合等一系列API,一些原本非常复杂的查询,使用Stream只需要几行代码就可以搞定,大大简化了代码的复杂度。

创建一个流

public void createStream() {    // list构建    Lists.newArrayList(1, 2, 3).stream();    // 数组构建    Arrays.stream(new int[]{1, 2, 3});    // 元素构建    Stream.of(1, 2, 3);    // 元素可以是不同类型的    Stream.of(1, 2, "a");    // 迭代器构建,迭代器构建的是一个无限流,必须要有限制    Stream.iterate(2, item -> item * 2).limit(5);}

过滤

public void filter() {    // 筛选出不等于“a”的元素    Stream.of(1, 2, "a").filter(item -> !item.equals("a")).forEach(System.out::println);    // 从1-10中筛选出大于5的奇数    IntStream.rangeClosed(1, 10).filter(item -> item % 2 == 1).filter(item -> item > 5).forEach(System.out::println);}

map转换

public void map() {    // mapToObj    IntStream.rangeClosed(1, 10)     .mapToObj(item -> new Order(item * 2))     .collect(Collectors.toList())     .forEach(System.out::println);    // mapToDouble    double sum = IntStream.rangeClosed(1, 10)     .mapToObj(item -> new Order(item * 2))     .collect(Collectors.toList())     .stream()     .mapToDouble(Order::getAmount)     .sum();    System.out.println(sum);}

flatMap 先展开再转换

public void flatMap() {    // 构建一个User集合    List<User> userList = IntStream.rangeClosed(1, 10)     .mapToObj(item -> new User("user_" + item,      IntStream.rangeClosed(1, item).mapToObj(role -> new Role("role_" + role)).collect(Collectors.toList())))     .collect(Collectors.toList());    // 遍历其中的Roles集合,看看map和flatMap的区别    userList.stream().map(User::getRoles).forEach(System.out::println);    userList.stream().flatMap(role -> role.getRoles().stream()).forEach(System.out::println);}

distinct 去重

public void distinct() {    List<User> userList = IntStream.rangeClosed(1, 10)     .mapToObj(item -> new User("user_" + item,      IntStream.rangeClosed(1, item).mapToObj(role -> new Role("role_" + role)).collect(Collectors.toList())))     .collect(Collectors.toList());    // 去重后重新拼接    System.out.println(userList.stream().flatMap(user -> user.getRoles().stream()).map(Role::getRole).distinct().collect(Collectors.joining(",")));}

sort 排序

public void sort() {    List<Order> orderList = IntStream.rangeClosed(1, 10)     .mapToObj(item -> new Order(item * 2))     .collect(Collectors.toList());    // sort+limit,输出前3大的amount    orderList.stream()     .sorted(Comparator.comparing(Order::getAmount).reversed())     .limit(3)     .collect(Collectors.toList())     .forEach(System.out::println);}

limit+skip 可实现分页

public void skip() {    List<Order> orderList = IntStream.rangeClosed(1, 10)     .mapToObj(item -> new Order(item * 2))     .collect(Collectors.toList());    // sort+limit+skip    orderList.stream()     .sorted(Comparator.comparing(Order::getAmount).reversed())     .skip(1)     .limit(3)     .collect(Collectors.toList())     .forEach(System.out::println);}

peek 用于执行结果前后查看,方便调试

public void peek() {    Stream.of("one", "two", "three", "four")     .filter(e -> e.length() > 3)     .peek(e -> System.out.println("Filtered value: " + e))     .map(String::toUpperCase)     .peek(e -> System.out.println("Mapped value: " + e))     .collect(Collectors.toList());}

collect 收集,是流的一种终止操作

public void collect() {    // 拼接字符串    String concat = Stream.of("a", "b", "c").collect(StringBuilder::new, StringBuilder::append,     StringBuilder::append)     .toString();    System.out.println(concat);    // 转成List集合    List<String> asList = Stream.of("a", "b", "c").collect(ArrayList::new, ArrayList::add,     ArrayList::addAll);    System.out.println(asList);    // 分隔符+前后缀    List<User> userList = IntStream.rangeClosed(1, 10)     .mapToObj(item -> new User("user_" + item,      IntStream.rangeClosed(1, item).mapToObj(role -> new Role("role_" + role)).collect(Collectors.toList())))     .collect(Collectors.toList());    System.out.println(     userList.stream()      .flatMap(user -> user.getRoles().stream())      .map(Role::getRole)      .distinct().      collect(Collectors.joining(",", "[", "]")));    List<User> users = IntStream.rangeClosed(1, 10)     .mapToObj(item -> new User("user_" + item,      IntStream.rangeClosed(1, item).mapToObj(role -> new Role("role_" + role)).collect(Collectors.toList())))     .collect(Collectors.toList());    // 转成Map形式    Map<String, List<Role>> collect = users.stream().collect(Collectors.toMap(User::getName, User::getRoles));    collect.entrySet().forEach(System.out::println);}

grouping 分组

public void grouping() {    List<Person> persons = Lists.newArrayList();    persons.add(new Person("a", "Nanjing", "Jiangsu"));    persons.add(new Person("b", "Nanjing", "Jiangsu"));    persons.add(new Person("c", "WuXi", "Jiangsu"));    persons.add(new Person("d", "WuXi", "Jiangsu"));    persons.add(new Person("e", "Hangzhou", "Zhejiang"));    persons.add(new Person("f", "Hangzhou", "Zhejiang"));    // 先按照省分组,再按照城市分组    Map<String, Map<String, List<Person>>> collect = persons.stream()     .collect(Collectors.groupingBy(Person::getProvince, Collectors.groupingBy(Person::getCity)));    collect.entrySet().forEach(System.out::println);    // 按照省分组,并统计出每个省的数量    persons.stream().collect(Collectors.groupingBy(Person::getProvince, Collectors.counting())).entrySet().forEach(System.out::println);    // 按照省分组,并计算出现次数最多的省    persons.stream().collect(Collectors.groupingBy(Person::getProvince, Collectors.counting())).entrySet().stream().max(Map.Entry.comparingByValue()).map(Map.Entry::getKey).ifPresent(System.out::println);}

partitioning 分区

public void partitioning() {    List<Person> persons = Lists.newArrayList();    persons.add(new Person("a", "Nanjing", "Jiangsu"));    persons.add(new Person("b", "Nanjing", "Jiangsu"));    persons.add(new Person("c", "WuXi", "Jiangsu"));    persons.add(new Person("d", "WuXi", "Jiangsu"));    persons.add(new Person("e", "Hangzhou", "Zhejiang"));    persons.add(new Person("f", "Hangzhou", "Zhejiang"));    // 按照城市分组,筛选出城市为“Nanjing”的信息    Stream<Map.Entry<String, List<Person>>> stream = persons.stream().collect(Collectors.groupingBy(Person::getCity)).entrySet().stream();    stream.filter(a -> a.getKey().equals("Nanjing")).forEach(System.out::println);    // 使用partitioningBy的方式,partitioningBy返回的分组只有true和false两种    persons.stream().collect(Collectors.partitioningBy(person -> person.getCity().equals("Nanjing"))).entrySet().stream()     .filter(Map.Entry::getKey).forEach(System.out::println);}

reduce 使用累计函数进行归约

public void reduce() {    // 累加计算    Integer sum = Stream.of(1, 2, 3, 4, 5).reduce(0, Integer::sum);    System.out.println(sum);}