java8新特性流式处理

1.Strem()流式处理

特点和特性

特性

  1. stream不存储数据,而是按照特定的规则对数据进行计算,一般会输出结果。
  2. stream不会改变数据源,通常情况下会产生一个新的集合或一个值。
  3. stream具有延迟执行特性,只有调用终端操作时,中间操作才会执行。

特点

  1. 代码简洁:函数编程写出的代码简洁且意图明确,使用stream接口让你从此告别for循环。
  2. 多核友好:Java函数式编程使得编写并行程序从未如此简单,你需要的全部就是调用一下方法。
  3. Stream不存储数据
  4. Stream不会改变源对象。相反,他们会返回一个持有结果的新Stream。
  5. Stream是惰性求值的(延迟执行)

创建Stream

        //返回一个顺序流
        Stream<String> stream = lists.stream();
        //返回一个并行流
        Stream<String> stream2 = lists.parallelStream();

中间操作

  1. 筛选切片

    方法描述
    distinct()筛选,通过流所生成元素的 hashCode() 和 equals() 去除重复元素
    limit(long maxSize)载断流,使其元素不超过给定数量
    skip(long n)跳过元素,返回一个扔掉了前 n 个元素的流。若流中元素不足 n 个,则返回一个空流。与 limit(n) 互补
    filter(Predicate p)接收 Lambda , 从流中排除某些元素
  2. 映射map

    方法描述
    map(Function f)接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素。
    mapToDouble(ToDoubleFunction f)接收一个函数作为参数,该函数会被应用到每个元素上,产生一个新的DoubleStream。
    mapTolnt(TolntFunction f)接收一个函数作为参数,该函数会被应用到每个元素上,产生一个新的IntStream。
    mapToLong(ToLongFunction f)接收一个函数作为参数,该函数会被应用到每个元素上,产生一个新的LongStream。
    flatMap(Function f)接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流
  3. 排序

    方法描述
    sorted()产生一个新流,其中按自然顺序排序
    sorted(Comparator com)产生一个新流,其中按比较器顺序排序

    终止操作

    1. 匹配与查找

      方法描述
      allMatch(Predicate p)检查是否匹配所有元素
      anyMatch(Predicate p)检查是否至少匹配一个元素
      noneMatch(Predicate p)检查是否没有匹配所有元素
      findFirst()返回第一个元素
      findAny()返回当前流中的任意元素
      count()返回流中元素总数
      max(Comparator c)返回流中最大值
      min(Comparator c)返回流中最小值
      forEach(Consumer c)内部迭代(使用Collection接口需要用户去做迭代,称为外部迭代)。相反,Stream API使用内部迭代—它帮你把迭代做了
    2. 归约

      方法描述
      reduce(T iden,BinaryOperator b)可以将流中元素反复结合起来,得到一个值。返回T
      reduce(BinaryOperator b)可以将流中元素反复结合起来,得到一个值。返回Optional
    3. 收集

      方法描述
      collect(Collector)将流转为其他形式。接收一个Collector接口的实现,用于给Stream中元素做汇总的方法

例子

1.根据某个属性过滤对象数组

 class Student{
            public Integer age;
            public String name;
            public String sex;
        }
        
        List<Student> students = new ArrayList<>();
        List<Student> result = students.stream().filter(student -> student.getSex().equals("女")).collect(Collectors.toList());

2.分组

List<Order> orders = Lists.newArrayList();
  
// 按照订单类型分组
Map<String, List<Order>> orderGroupMap = orders.stream().collect(Collectors.groupingBy(Order::getType));

3.去重

List<Order> orders = Lists.newArrayList();
  
// 按照订单编号去重
orders = orders.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(()
          -> new TreeSet<>(Comparator.comparing(Order::getNum))), ArrayList::new));
 
// 按照订单编号和类型去重
orders = orders.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(()
          -> new TreeSet<>(Comparator.comparing(o -> o.getNum() + ";" + o.getType()))), ArrayList::new));

4.List转Map

List<Order> orders = Lists.newArrayList();
  
// 将订单集合转换成订单编号-应付金额 map,注意订单编号作为 key 不能重复,应先做去重处理
Map<String, Float> numPayMap = orders.stream().collect(Collectors.toMap(Order::getNum, Order::getPayAmt));
 
// 用 id 做 key 将 List 转成 Map
Map<Long, Order> orderMap = orders.stream().collect(Collectors.toMap(Order::getId, item -> item));

5.排序

List<Order> orders = Lists.newArrayList();
  
  // 按照订单总金额从高到低排序
  // 方式一
  orders.sort((o1, o2)
          -> o1.getAllAmt() == null ? 1 : (o2.getAllAmt() == null ? -1 : o2.getAllAmt().compareTo(o1.getAllAmt())));
 
  // 方式二
  orders.sort(Comparator.comparing(Order::getAllAmt, (o1, o2)
          -> o1 == null ? 1 : (o2 == null ? -1 : o2.compareTo(o1))));
 
  // 方式三 (allAmt 字段不能为 null, null 会导致排序失败)
  orders.sort(Comparator.comparing(Order::getAllAmt).reversed());
 
  // 先按照订单类型排序,再按照订单应付金额从高到低排序
  orders.sort(Comparator.comparing(Order::getType, (o1, o2)
          -> o1 == null ? 1 : (o2 == null ? -1 : o1.compareTo(o2))).thenComparing((o1, o2)
          -> o1.getPayAmt() == null ? 1 : (o2.getPayAmt() == null ? -1 : o2.getPayAmt().compareTo(o1.getPayAmt()))));

6.统计计数

List<Order> orders = Lists.newArrayList();
  
  // 统计所有订单的总金额
  // 求和
  Double sum = orders.stream().filter(item -> item.getAllAmt() != null).mapToDouble(Order::getAllAmt).sum();
 
  // 最大总金额
  OptionalDouble max = orders.stream().filter(item -> item.getAllAmt() != null).mapToDouble(Order::getAllAmt).max();
  // 防止没有订单数据的处理
  Double maxAllAmt = max.isPresent() ? max.getAsDouble() : 0;
  
  // 最小总金额
  OptionalDouble min = orders.stream().filter(item -> item.getAllAmt() != null).mapToDouble(Order::getAllAmt).min();
 
  // 平均总金额
  OptionalDouble average = orders.stream().filter(item -> item.getAllAmt() != null).mapToDouble(Order::getAllAmt).average();
  • 5
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
Java 8引入了许多新特性,以下是其中一些重要的特性: 1. Lambda表达式:Lambda表达式是Java 8中最重要的特性之一。它允许我们以更简洁的方式编写匿名函数。Lambda表达式可以作为参数传递给方法,或者用于函数式接口的实现。 2. 函数式接口:函数式接口是只包含一个抽象方法的接口。Java 8引入了一些新的函数式接口,如`Predicate`、`Consumer`、`Supplier`和`Function`等。这些接口可以与Lambda表达式一起使用,使得编写函数式代码更加方便。 3. Stream API:Stream API是Java 8中处理集合数据的新方式。它提供了一种流式操作集合的方式,可以进行过滤、映射、排序等操作。Stream API可以大大简化集合数据的处理,并且可以利用多核处理器进行并行操作。 4. 默认方法:默认方法是接口中的一个新特性,它允许在接口中定义具有默认实现的方法。这样一来,当接口的实现类没有实现该方法时,就会使用默认实现。 5. 方法引用:方法引用是一种更简洁地调用已经存在的方法的方式。它可以替代Lambda表达式,使得代码更加简洁易读。 6. 新的日期和时间API:Java 8引入了全新的日期和时间API,取代了旧的`java.util.Date`和`java.util.Calendar`类。新的API提供了更好的日期和时间处理方式,并且支持时区、日历等功能。 7. Optional类:Optional类是一个容器对象,可以包含null或非null的值。它可以避免空指针异常,并且提供了一些便利的方法来处理可能为空的值。 8. 并发增强:Java 8对并发编程进行了一些增强,引入了新的并发工具类,如`CompletableFuture`和`StampedLock`,以及新的并行操作方式。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

The outsider�

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

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

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

打赏作者

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

抵扣说明:

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

余额充值