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

前言

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);
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码拉松

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值