Java Stream流

文章目录

  • 前言
  • Stream是什么
  • Stream流语法
  • Stream流的常用方法
  • 代码示例


前言

Java 8 API添加了一个新的抽象称为流Stream,可以让你以一种声明的方式处理数据。

Stream 使用一种类似用 SQL 语句从数据库查询数据的直观方式来提供一种对 Java 集合运算和表达的高阶抽象。

Stream API可以极大提高Java程序员的生产力,让程序员写出高效率、干净、简洁的代码。

这种风格将要处理的元素集合看作一种流,流在管道中传输,并且可以在管道的节点上进行处理,比如筛选,排序,聚合等。

元素流在管道中经过中间操作(intermediate operation)的处理,最后由最终操作(terminal operation)得到前面处理的结果。


Stream是什么

Stream(流)是一个来自数据源的元素队列并支持聚合操作

  • 元素是特定类型的对象,形成一个队列。Java中的Stream并不会存储元素,而是按需计算。
  • 数据源 流的来源。可以是集合,数组,I/O channel,产生器generator 等。
  • 聚合操作 类似SQL语句一样的操作,比如filter, map, reduce, find, match, sorted等。

和以前的Collection操作不同,Stream操作还有两个基础的特征:

  • Pipelining: 中间操作都会返回流对象本身。这样多个操作可以串联成一个管道,如同流式风格(fluent style)。这样做可以对操作进行优化,比如延迟执行(laziness)和短路( short-circuiting)。
  • 内部迭代: 以前对集合遍历都是通过Iterator或者For-Each的方式, 显式的在集合外部进行迭代,这叫做外部迭代。Stream提供了内部迭代的方式,通过访问者模式(Visitor)实现。

Stream流语法

| stream of elements +> |filter±> |sorted±> |map±> |collect|

Stream流的常用方法

  • 终结方法:返回值类型不再是Stream接口本身类型的方法,例如:forEach方法和count方法
  • 非终结方法/延迟方法:返回值类型仍然是Stream接口自身类型的方法,除了终结方法都是延迟方法。例如:filter,limit,skip,map,conat
方法名称 方法作用 方法种类 是否支持链式调用
count 统计个数 终结方法
forEach 迭代处理 终结方法
filter 过滤 函数拼接
limit 取用前几个 函数拼接
skip 跳过前几个 函数拼接
map 映射 函数拼接
flatMap 扁平化映射 函数拼接
concat 组合 函数拼接
distinct 去重 函数拼接
sorted 排序 函数拼接
peek 流中调用 函数拼接
reduce 归约操作 终结方法
min 最小值操作 终结方法
max 最大值操作 终结方法
anyMatch 匹配任意元素操作 终结方法
allMatch 匹配所有元素操作 终结方法
noneMatch 没有匹配元素操作 终结方法
collect 集合操作 终结方法

代码示例

public class Test {

    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("一往情深");
        list.add("石昊");
        list.add("秦昊");
        list.add("石中天");
        // 过滤出名字结尾有“昊”的名字
        list.stream().filter(p -> p.endsWith("昊")).forEach(p -> {
            System.out.println("符合条件的姓名:" + p);
        });

        System.out.println("--------------------------------");

        // 过滤出名字第一个字有“石”的名字,并且名字长度是3个数
        list.stream().filter(p -> p.startsWith("石")).filter(p -> p.length() == 3).forEach(p -> {
            System.out.println("符合条件的姓名:" + p);
        });
    }
}

输出:

符合条件的姓名:石昊
符合条件的姓名:秦昊
--------------------------------
符合条件的姓名:石中天

public class Test {

    public static void main(String[] args) {
        String str = "一往情深  ,石昊,秦昊,石中天, , 一往情深,AA,aa";
        // 1. 按“,”分割成数组
        // 2. 去除左右两边空格
        // 3. 转小写
        // 4. 过滤出不为空的
        // 5. 去重
        Arrays.stream(str.split(",")).map(String::trim).map(String::toLowerCase).filter(StringUtil::isNotEmpty).distinct().collect(Collectors.toList()).forEach(s -> {
            switch (s) {
                case "一往情深":
                    System.out.println("作者:" + s);
                    break;
                case "石昊":
                    System.out.println("这个就厉害了:" + s);
                    break;
                default:
                    System.out.println(s);
                    break;
            }
        });
    }
}

输出:

作者:一往情深
这个就厉害了:石昊
秦昊
石中天
aa

public class Test {

    public static void main(String[] args) {
        // stream()操作对象示例
        List<User> userList = new ArrayList<>();
        userList.add(new User(1, "1号选手"));
        userList.add(new User(2, "2号选手"));
        userList.add(new User(3, "3号选手"));
        // 过滤出id大于1的User
        System.out.println(userList.stream().filter(p -> p.getId() > 1).collect(Collectors.toList()));

        // 1. 按id倒序,从大到小
        // 2. 过滤出name中不包含2的User对象
        System.out.println(userList.stream().sorted(Comparator.comparing(User::getId).reversed()).filter(p -> !p.getName().contains("2")).collect(Collectors.toList()));
    }
}

@Getter
@ToString
class User {
    private Integer id;
    private String name;

    public User(Integer id, String name) {
        this.id = id;
        this.name = name;
    }
}

输出:

[User(id=2, name=2号选手), User(id=3, name=3号选手)]
[User(id=3, name=3号选手), User(id=1, name=1号选手)]

public class test {

    public static void main(String[] args) {
        List<Integer> numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5);
		
		// 统计
        IntSummaryStatistics stats = numbers.stream().mapToInt((x) -> x).summaryStatistics();

        System.out.println("列表中最大的数 : " + stats.getMax());
        System.out.println("列表中最小的数 : " + stats.getMin());
        System.out.println("所有数之和 : " + stats.getSum());
        System.out.println("平均数 : " + stats.getAverage());
    }
}

输出:

列表中最大的数 : 7
列表中最小的数 : 2
所有数之和 : 25
平均数 : 3.5714285714285716

你可能感兴趣的:(Java,java)