zoukankan      html  css  js  c++  java
  • jdk1.8 新特性之Stream

    --------------------- 
    作者:码农农码一生 
    来源:CSDN 
    原文:https://blog.csdn.net/chenhao_c_h/article/details/80691284 

    虽然java 10已经发布,11 已经在路上,虽然 java EE 已经更名为 jakarta EE,但是大多数人连jdk1.8的新特性都不太了解,本人也是如此,所以在学习Java 8 API 添加的 Stream 的时候 做一些个人笔记,希望帮助自己的同时也能帮到大家。

    首先对stream的操作可以分为两类,中间操作(intermediate operations)和结束操作(terminal operations):

    中间操作总是会惰式执行,调用中间操作只会生成一个标记了该操作的新stream。
    结束操作会触发实际计算,计算发生时会把所有中间操作积攒的操作以pipeline的方式执行,这样可以减少迭代次数。计算完成之后stream就会失效。
    虽然大部分情况下stream是容器调用Collection.stream()方法得到的,但stream和collections有以下不同:

    无存储。stream不是一种数据结构,它只是某种数据源的一个视图,数据源可以是一个数组,Java容器或I/O channel等。
    为函数式编程而生。对stream的任何修改都不会修改背后的数据源,比如对stream执行过滤操作并不会删除被过滤的元素,而是会产生一个不包含被过滤元素的新stream。
    惰式执行。stream上的操作并不会立即执行,只有等到用户真正需要结果的时候才会执行。
    可消费性。stream只能被“消费”一次,一旦遍历过就会失效,就像容器的迭代器那样,想要再次遍历必须重新生成。
     

    一、获取stream
    // 1、数组
    String[] arr = new String[]{"ab", "cd", "ef"};
    Stream<String> arrStream = Arrays.stream(arr);
    // 2、集合
    List<String> list = Arrays.asList("ab", "cd", "ef");
    Stream<String> colStream = list.stream();
    // 3、值
    Stream<String> stream = Stream.of("ab", "cd", "ef");
    二、stream方法使用
    测试数据:

    List<User> list = Arrays.asList(
    // name,age
    new User("张三", 11),
    new User("王五", 20),
    new User("王五", 91),
    new User("张三", 8),
    new User("李四", 44),
    new User("李四", 44),
    new User("李四", 44)
    );
    1、forEach() 使用该方法迭代流中的每个数据
    /**
    * forEach 迭代输出每条数据.
    */
    @Test
    public void testForEach(){
    // java 8 前
    System.out.println("java 8 前");
    for(User user: list){
    System.out.println(user);
    }
    // java 8 lambda
    System.out.println("java 8 lambda");
    list.forEach(user -> System.out.println(user));

    // java 8 stream lambda
    System.out.println("java 8 stream lambda");
    list.stream().forEach(user -> System.out.println(user));
    }
    console->

    2、sorted() 使用该方法排序数据
    /**
    * sort 排序.
    */
    @Test
    public void testSort() {
    System.out.println("-----排序前-----");
    list.forEach(user -> System.out.println(user));
    System.out.println("-----排序后-----");
    // java 8 前
    System.out.println("java 8 前");
    Collections.sort(list, new Comparator<User>() {
    @Override
    public int compare(User o1, User o2) {
    return o1.getAge().compareTo(o2.getAge());
    }
    });
    for (User user : list) {
    System.out.println(user);
    }
    // java 8 stream 方法引用
    System.out.println("java 8 stream 方法引用");
    list.stream().sorted(Comparator.comparing(User::getAge)).forEach(user -> System.out.println(user));
    }
    console->

    3、filter():使用该方法过滤
    /**
    * filter 过滤.
    */
    @Test
    public void testFilter() {
    // 输出年龄大于50的人
    System.out.println("-----过滤前-----");
    list.forEach(user -> System.out.println(user));
    System.out.println("-----过滤后-----");
    // java 8 前
    System.out.println("java 8 前");
    for(User user: list){
    if (user.getAge() > 50) {
    System.out.println(user);
    }
    }
    // java 8 stream
    System.out.println("java 8 stream");
    list.stream().filter((User user) -> user.getAge() > 50).forEach(user -> System.out.println(user));
    }
    console->

    4、limit():使用该方法截断
    /**
    * limit 截断.
    */
    @Test
    public void testLimit() {
    // 从第三个开始截断,只输出前三个
    System.out.println("-----截断前-----");
    list.forEach(user -> System.out.println(user));
    System.out.println("-----截断后-----");
    // java 8 前
    System.out.println("java 8 前");
    for (int i = 0; i < 3; i++) {
    System.out.println(list.get(i));
    }
    // java 8 stream
    System.out.println("java 8 stream");
    list.stream().limit(3).forEach(user -> System.out.println(user));
    }
    console->

    5、skip():与limit互斥,使用该方法跳过元素
    /**
    * skip 跳过.
    */
    @Test
    public void testSkip() {
    // 跳过前三个元素,从第四个开始输出
    System.out.println("-----跳过前-----");
    list.forEach(user -> System.out.println(user));
    System.out.println("-----跳过后-----");
    // java 8 前
    System.out.println("java 8 前");
    for (int i = 3; i < list.size(); i++) {
    System.out.println(list.get(i));
    }
    // java 8 stream
    System.out.println("java 8 stream");
    list.stream().skip(3).forEach(user -> System.out.println(user));
    }
    console->

    6、distinct():使用该方法去重,注意:必须重写对应泛型的hashCode()和equals()方法
    /**
    * distinct 去重.
    */
    @Test
    public void testDistinct() {
    // 因为Arrays.asList() 返回的是Arrays的内部类ArrayList,操作remove,add会报错
    List<User> users = new ArrayList(list);
    // 为list去除重复数据
    System.out.println("-----去重前-----");
    list.forEach(user -> System.out.println(user));
    System.out.println("-----去重后-----");
    // java 8 前
    System.out.println("java 8 前");
    for (int i = 0; i < users.size() - 1; i++) {
    for (int j = users.size() - 1; j > i; j--) {
    if (users.get(j).getAge() == users.get(i).getAge() && users.get(j).getName()
    .equals(users.get(i).getName())) {
    users.remove(i);
    }
    }
    }
    for (User user : users) {
    System.out.println(user);
    }
    // java 8 stream
    System.out.println("java 8 stream");
    users.stream().distinct().forEach(user -> System.out.println(user));
    }
    console->

    ***根据上述方法,完成去重+按照年龄大于40以后从小到大+只取前二

    /**
    * 去重+按照年龄大于40以后从小到大+只取前二
    */
    @Test
    public void demo() {
    list.stream().distinct().filter(user -> user.getAge() > 40).sorted(
    Comparator.comparing(User::getAge)).limit(2).forEach(user -> System.out
    .println(user));
    }
    console->

    7、max,min,sum,avg,count 
    /**
    * 测试计算.
    */
    @Test
    public void testNum() {
    IntSummaryStatistics num = list.stream().mapToInt(u -> u.getAge())
    .summaryStatistics();
    System.out.println("总共人数:" + num.getCount());
    System.out.println("平均年龄:" + num.getAverage());
    System.out.println("最大年龄:" + num.getMax());
    System.out.println("最小年龄:" + num.getMin());
    System.out.println("年龄之和:" + num.getSum());
    }
    console->

    8、map():接收一个方法作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素
    /**
    * map 映射.
    */
    @Test
    public void testMap() {
    // 只输出所有人的年龄
    list.stream().forEach(user -> System.out.println(user));
    System.out.println("映射后----->");
    List<Integer> ages = list.stream().map(user -> user.getAge()).collect(toList());
    ages.forEach(age -> System.out.println(age));

    // 小写转大写
    List<String> words = Arrays.asList("aaa", "vvvv", "cccc");
    System.out.println("全部大写---->");
    List<String> collect = words.stream().map(s -> s.toUpperCase()).collect(toList());
    collect.forEach(s -> System.out.println(s));
    }
    console->

    9、flatMap():对每个元素执行mapper指定的操作,并用所有mapper返回的Stream中的元素组成一个新的Stream作为最终返回结果,通俗易懂就是将原来的stream中的所有元素都展开组成一个新的stream
    /**
    * flatMap .
    */
    @Test
    public void testFlatMap() {
    //创建一个 装有两个泛型为integer的集合
    Stream<List<Integer>> stream = Stream.of(Arrays.asList(1, 2, 3), Arrays.asList(4, 5));
    // 将两个合为一个
    Stream<Integer> integerStream = stream.flatMap(
    (Function<List<Integer>, Stream<Integer>>) integers -> integers.stream());
    // 为新的集合
    List<Integer> collect = integerStream.collect(toList());
    System.out.println("新stream大小:"+collect.size());
    System.out.println("-----合并后-----");
    collect.forEach(o -> System.out.println(o));
    }
    console->

    10、findFirst() :使用该方法获取第一个元素
    /**
    * findFirst 获取第一个元素.
    */
    @Test
    public void testFindFirst(){
    User user = list.stream().findFirst().get();
    System.out.println(user);
    }
    console->

  • 相关阅读:
    推荐系统 蒋凡译 第一章 引言 读书笔记
    神经网络与深度学习 邱锡鹏 第5章 卷积神经网络 读书笔记
    神经网络与深度学习 邱锡鹏 第4章 前馈神经网络 读书笔记
    神经网络与深度学习 邱锡鹏 第3章 线性模型 读书笔记
    神经网络与深度学习 邱锡鹏 第2章 机器学习概述 读书笔记
    神经网络与深度学习 邱锡鹏 第1章 绪论 作业
    神经网络与深度学习 邱锡鹏 第1章 绪论 读书笔记
    算法笔记 上机训练实战指南 第13章 专题扩展 学习笔记
    算法笔记 第13章 专题扩展 学习笔记
    算法笔记 上机训练实战指南 第11章 提高篇(5)--动态规划专题 学习笔记
  • 原文地址:https://www.cnblogs.com/xiaokangk/p/11098409.html
Copyright © 2011-2022 走看看