JAVA8 Stream流式编程的去重、过滤、映射(map)、分组、统计(sum、max、min、avg)、分页

概念及其特征

  • Java的Stream流是在Java 8中引入的一种用于处理集合数据的功能强大且易于使用的工具,旨在简化集合框架的操作。它的设计目的是为了提供一种更简洁、更灵活和更可读的方式来处理集合数据。
  • Stream流是对集合进行操作的高级抽象,可以将集合看作是一种源(source),而Stream表示这个源上进行的计算操作序列。 通过使用Stream API,我们可以以流水线方式处理数据,并进行各种转换和聚合操作。
  • Java中有两种流:流(Stream)表示顺序流,按照数据源的顺序进行操作,适用于串行操作;并行流(ParallelStream),可以同时对数据源的多个元素进行操作,适用于并行计算。

流式编程具有以下特点: 

  • 流是一次性的:流不会保存元素,它仅仅描述了操作的序列,并且在执行聚合操作之后就被消耗掉了。即使我们对一个流执行多个操作,每个操作也只会在需要输出结果时才会执行,并且在执行完毕后,流不能再次使用。这与传统的集合不同,集合可以随时进行增删元素的操作;
  • 流是无状态的:流的操作不会修改原始数据结构,而是通过创建一个新的流来执行操作,并最终返回一个结果。原始数据结构保持不变,这种无状态的特性使得流操作可以并行处理数据,不用担心多线程下的数据竞争问题; 
  • 流是延迟执行的:流的操作被称为延迟执行,也就是说,在流的聚合操作被触发之前,中间操作不会立即执行。这意味着我们可以先构建一个复杂的流操作链,然后在需要结果的时候才触发最终的操作。这种延迟执行的机制有助于优化性能,避免不必要

Stream流的实现原理主要基于迭代器和函数式编程的思想。在内部迭代的过程中,流通过一系列操作进行链式处理,将每个元素传递给下一个操作,并最终生成结果。

在并行流的情况下,流将输入数据分成多个小块,分配给不同的线程并行处理。处理完后,再合并结果并返回。

使用语法

Stream提供了两种类型的操作——中间操作和终端操作。中间操作用于链式调用,并可以有多个,而终端操作是触发计算的地方。使用Stream主要分为三个步骤:

  • 创建流:也即获取一个Stream对象,可以通过集合、数组或者其他方式创建一个Stream。如可以使用Stream.of()方法创建流;
  • 进行中间操作:对Stream进行连续的中间操作,包括过滤、映射、排序、去重等处理。如可以使用forEach()方法遍历流中的元素,并使用filter()map()sorted()等方法对流进行操作;
  • 执行终结操作:最后使用一个终结操作来触发计算并产生结果,如收集、聚合、遍历等。如可以使用reduce()方法进行元素的归约操作,使用collect()方法进行元素的收集操作。

常用的操作: 

  • 去重(distinct): list = list.stream().distinct().collect(Collectors.toList())。底层原理是通过将 List类型 转换为 LinkedSet类型后,根据equals()方法和对象的hashCode()去重 的方式去重。

示例1:根据List集合对象的name属性进行去重:

方法一核心代码:list = list.stream().filter(o -> o.getName() != null).collect(
                Collectors.collectingAndThen(Collectors.toCollection(
                    () -> new TreeSet<>(Comparator.comparing(o -> o.getName()))), ArrayList<Aoo>::new)); 

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.TreeSet;
import java.util.stream.Collectors;
 
public class Test {
    public static void main(String[] args) {
        List<Aoo> list = Arrays.asList(new Aoo("a.name"), new Aoo("b.name"), new Aoo("c.name"));
        System.out.println("list before operate : " + list);
        list = list.stream().filter(o -> o.getName() != null).collect(
                Collectors.collectingAndThen(Collectors.toCollection(
                    () -> new TreeSet<>(Comparator.comparing(o -> o.getName()))), ArrayList<Aoo>::new));
        System.out.println("list after operate : " + list);
    }
}
class Aoo {
    private String name;
 
    public Aoo(String name) {
        this.name = name;
    }
    public Aoo() {}
  • 22
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Aplis

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

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

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

打赏作者

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

抵扣说明:

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

余额充值