Java8 Stream简单示例

博客展示了一个简单示例,虽未给出具体内容,但突出了示例的简单特性。

目录

简单示例

package com.grandsun.wxpay.java8NewFeature;/**
 * Created by admin on 2020/11/20.
 */

import org.junit.Test;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.text.DecimalFormat;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;

/**
 * 文件名:StreamTest
 *
 * @author: zenghl
 * 时间:2020/11/20 4:36 PM
 * 描述:Stream测试
 *  参考: https://developer.ibm.com/zh/articles/j-lo-java8streamapi/
 *
 */
public class StreamTest {



    public Stream<String> getStreamData(){
        String [] strArray = new String[] {"1", "2", "3"};
        List<String> dataList = Arrays.asList(strArray);
        Stream<String> stream = dataList.stream();
        return stream;

    }

    public Stream<String> getStreamW(){
        String [] strArray = new String[] {"a", "b", "c","d","e"};
        List<String> dataList = Arrays.asList(strArray);
        Stream<String> stream = dataList.stream();
        return stream;

    }

    public class Person{
        private int no;
        private String name;
        private String sex;
        private Integer age;

        public Person(){

        }

        public Person(Integer no, String name){
            this.no = no;
            this.name = name;
        }

        public Person(Integer no, String name, Integer age){
            this.no = no;
            this.name = name;
            this.age = age;
        }

        public Person(String name, String sex, String gender){
            this.name = name;
            this.sex = sex;
        }

        public int getNo() {
            return no;
        }

        public void setNo(int no) {
            this.no = no;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public String getSex() {
            return sex;
        }

        public void setSex(String sex) {
            this.sex = sex;
        }

        public Integer getAge() {
            return age;
        }

        public void setAge(Integer age) {
            this.age = age;
        }


        @Override
        public String toString() {
            return "Person{" +
                    "no=" + no +
                    ", name='" + name + '\'' +
                    ", sex='" + sex + '\'' +
                    '}';
        }
    }

    /**
     * 构造流的几种常见方法
     */
    @Test
    public void demo1(){
        // 1. Individual values
        Stream stream = Stream.of("a", "b", "c");
        // 2. Arrays
        String [] strArray = new String[] {"a", "b", "c"};
        stream = Stream.of(strArray);
        stream = Arrays.stream(strArray);
        // 3. Collections
        List<String> list2 = Arrays.asList(strArray);
        stream = list2.stream();

    }


    /**
     * 数值流的构造
     */
    @Test
    public void demo2(){
        IntStream.of(new int[]{1, 2, 3}).forEach(System.out::println);
        IntStream.range(1, 30).forEach(System.out::println);
        IntStream.rangeClosed(1, 13).forEach(System.out::println);

    }


    /**
     * 流转换为其它数据结构
     */
    @Test
    public void demo3(){
        // 1. Array
        Stream<String> stream = getStreamData();
        String[] strArray1 = stream.toArray(String[]::new);

        // 2. Collection
        stream = getStreamData();
        List<String> list1 = stream.collect(Collectors.toList());

        stream = getStreamData();
        List<String> list2 = stream.collect(Collectors.toCollection(ArrayList::new));

        stream = getStreamData();
        Set set1 = stream.collect(Collectors.toSet());

        stream = getStreamData();
        Stack stack1 = stream.collect(Collectors.toCollection(Stack::new));

        // 3. String
        stream = getStreamData();
        String str = stream.collect(Collectors.joining()).toString();

        //stream.collect(Collectors.);

    }


    /**
     * 转换大写
     */
    @Test
    public void demo4(){
        List<String> output = getStreamW()
                .map(String::toUpperCase)
                .collect(Collectors.toList());
        System.out.println(output);
    }


    /**
     *  平方数
     */
    @Test
    public void demo5(){
        List<Integer> nums = Arrays.asList(1, 2, 3, 4);
        List<Integer> squareNums = nums.stream().
                map(n -> n * n).
                collect(Collectors.toList());
        System.out.println(squareNums);
    }


    /**
     * 一对多
     */
    @Test
    public void demo6(){
        Stream<List<Integer>> inputStream = Stream.of(
                Arrays.asList(1),
                Arrays.asList(2, 3),
                Arrays.asList(4, 5, 6)
        );
        Stream<Integer> outputStream = inputStream.
                flatMap((childList) -> childList.stream());
        outputStream.forEach(System.out::println);
    }

    /**
     * 留下偶数
     */
    @Test
    public void demo7(){
        Integer[] sixNums = {1, 2, 3, 4, 5, 6};
        Integer[] evens =
                Stream.of(sixNums).filter(n -> n%2 == 0).toArray(Integer[]::new);
        Arrays.stream(evens).forEach(System.out::println);
    }


    /**
     * 把单词挑出来
     */
    @Test
    public void demo8() {
        String sentence = "if you are luck you can catch a glimpse!" ;
        String[] sentences = {"if you are luck you can catch a glimpse!", "hi, how are you!", "same as always"};
        Stream<String> stream = Stream.of(sentence);

//        List<String> output = reader.lines().
//                flatMap(line -> Stream.of(reader.split(" "))).
//                filter(word -> word.length() > 0).
//                collect(Collectors.toList());
    }


    /**
     * 打印姓名(forEach 和 pre-java8 的对比)
     */
    @Test
    public void demo9(){
        List<Person> personList = new ArrayList<>();
        personList.add(new Person("张三", "男", ""));
        personList.add(new Person("小花", "女", ""));
        personList.add(new Person("王五", "男", ""));

        // Java 8
        personList.stream()
                .filter(p -> p.getSex() == "男")
                .forEach(p -> System.out.println(p.getName()));

        // Java 8
        Object[] array = Stream.of(1, 2, 3, 11, 22, 33, 99, -1, -2, -3)
                .toArray();
        Stream.of(array)
                .forEachOrdered(System.out::println);


        // Pre-Java 8
        for (Person p : personList) {
            if (p.getSex() == "女") {
                System.out.println(p.getName());
            }
        }
    }


    /**
     *  terminal 操作,因此它执行后,Stream 的元素就被”消费”掉了,你无法对一个 Stream 进行两次 terminal 运算。
     *
     *  错误示例:
     *  运行会报错「java.lang.IllegalStateException: stream has already been operated upon or closed」
     */
    @Test
    public void demo10(){
        Stream<String> stream = getStreamData();
        stream.forEach(element -> System.out.println());
        stream.forEach(element -> System.out.println());
    }


    /**
     * 清单 13. peek 对每个元素执行操作并返回一个新的 Stream
     * forEach 不能修改自己包含的本地变量值,也不能用 break/return 之类的关键字提前结束循环
     *
     **/
    @Test
    public void demo11(){
        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());
    }


    /**
     * 清单 14. Optional 的两个用例
     *
     *  在更复杂的 if (xx != null) 的情况中,使用 Optional 代码的可读性更好,而且它提供的是编译时检查,能极大的降低 NPE 这种 Runtime Exception 对程序的影响,或者迫使程序员更早的在编码阶段处理空值问题,而不是留到运行时再发现和调试。

     Stream 中的 findAny、max/min、reduce 等方法等返回 Optional 值。还有例如 IntStream.average() 返回 OptionalDouble 等等。

     */
    @Test
    public void demo12(){
        String strA = " abcd ", strB = null;
        print(strA);
        print("");
        print(strB);
        getLength(strA);
        getLength("");
        getLength(strB);

    }
    public static void print(String text) {
        // Java 8
        Optional.ofNullable(text).ifPresent(System.out::println);
        Optional.ofNullable(new String());

        // Pre-Java 8
//        if (text != null) {
//            System.out.println(text);
//        }
    }
    public static void getLength(String text) {
        // Java 8
        System.out.println(Optional.ofNullable(text).map(String::length).orElse(-1));

        // Pre-Java 8
        // return if (text != null) ? text.length() : -1;
    }



    /**
     * 清单 15. reduce 的用例
     *
     * 这个方法的主要作用是把 Stream 元素组合起来。它提供一个起始值(种子),然后依照运算规则(BinaryOperator),和前面 Stream 的第一个、第二个、第 n 个元素组合。从这个意义上说,字符串拼接、数值的 sum、min、max、average 都是特殊的 reduce。例如 Stream 的 sum 就相当于

     Integer sum = integers.reduce(0, (a, b) -> a+b); 或

     Integer sum = integers.reduce(0, Integer::sum);

     也有没有起始值的情况,这时会把 Stream 的前面两个元素组合起来,返回的是 Optional。


     */
    @Test
    public void demo13(){
        // 字符串连接,concat = "ABCD"
        String concat = Stream.of("A", "B", "C", "D").reduce("", String::concat);
        System.out.println(concat);

        // 求最小值,minValue = -3.0
        double minValue = Stream.of(-1.5, 1.0, -3.0, -2.0).reduce(Double.MAX_VALUE, Double::min);
        System.out.println(minValue);

        // 求和,sumValue = 10, 有起始值
        int sumValue = Stream.of(1, 2, 3, 4).reduce(0, Integer::sum);
        System.out.println(sumValue);

        // 求和,sumValue = 10, 无起始值
        sumValue = Stream.of(1, 2, 3, 4).reduce(Integer::sum).get();
        System.out.println(sumValue);

        // 过滤,字符串连接,concat = "ace"
        concat = Stream.of("a", "B", "c", "D", "e", "F").
                filter(x -> x.compareTo("Z") > 0).
                reduce("", String::concat);
        System.out.println(concat);
    }


    /**
     * 清单 16. limit 和 skip 对运行次数的影响
     *
     * limit/skip

     limit 返回 Stream 的前面 n 个元素;skip 则是扔掉前 n 个元素(它是由一个叫 subStream 的方法改名而来)。
     */
    @Test
    public void demo14(){
        List<Person> persons = new ArrayList();
        for (int i = 1; i <= 10000; i++) {
            Person person = new Person(i, "name" + i);
            persons.add(person);
        }
        List<String> personList2 = persons.stream().
                map(Person::getName).limit(10).skip(3).collect(Collectors.toList());
        System.out.println(personList2);
    }

    /**
     * 清单 18. 优化:排序前进行 limit 和 skip
     *
     * sorted

     对 Stream 的排序通过 sorted 进行,它比数组的排序更强之处在于你可以首先对 Stream 进行各类 map、filter、limit、skip 甚至 distinct 来减少元素数量后,再排序,这能帮助程序明显缩短执行时间。我们对清单 14 进行优化:
     */
    @Test
    public void demo15(){
        List<Person> persons = new ArrayList();
        for (int i = 1; i <= 5; i++) {
            Person person = new Person(i, "name" + i);
            persons.add(person);
        }
        List<Person> personList2 = persons.stream()
                .limit(2)
                .sorted((p1, p2) -> p1.getName().compareTo(p2.getName()))
                .collect(Collectors.toList());
        System.out.println(personList2);

    }


    /**
     * 清单 19. 找出最长一行的长度
     * @throws IOException
     */
    @Test
    public void demo16() throws IOException {
        BufferedReader br = new BufferedReader(new FileReader("/Users/admin/Desktop/gs_project/kuais_health/log/cleer.2020-09-05.0.log"));
        int longest = br.lines().
                mapToInt(String::length).
                max().
                getAsInt();
        br.close();
        System.out.println(longest);
    }


    /**
     * 清单 20. 找出全文的单词,转小写,并排序
     */
    @Test
    public void demo17() throws IOException {
        BufferedReader br = new BufferedReader(new FileReader("/Users/admin/Desktop/gs_project/kuais_health/sql/kuais_health.lock.md"));

        List<String> words = br.lines().
                flatMap(line -> Stream.of(line.split(" "))).
                filter(word -> word.length() > 0).
                map(String::toLowerCase).
                distinct().
                sorted().
                collect(Collectors.toList());
        br.close();
        System.out.println(words);
    }


    /**
     * Match

     Stream 有三个 match 方法,从语义上说:

     allMatch:Stream 中全部元素符合传入的 predicate,返回 true
     anyMatch:Stream 中只要有一个元素符合传入的 predicate,返回 true
     noneMatch:Stream 中没有一个元素符合传入的 predicate,返回 true
     它们都不是要遍历全部元素才能返回结果。例如 allMatch 只要一个元素不满足条件,就 skip 剩下的所有元素,返回 false。对清单 13 中的 Person 类稍做修改,加入一个 age 属性和 getAge 方法。

     清单 21. 使用 Match
     */
    @Test
    public void demo18(){
        List<Person> persons = new ArrayList();
        persons.add(new Person(1, "name" + 1, 10));
        persons.add(new Person(2, "name" + 2, 21));
        persons.add(new Person(3, "name" + 3, 34));
        persons.add(new Person(4, "name" + 4, 6));
        persons.add(new Person(5, "name" + 5, 55));

        //全匹配
        boolean isAllAdult = persons.stream().
                allMatch(p -> p.getAge() > 18);
        System.out.println("All are adult? " + isAllAdult);

        //有匹配
        boolean isThereAnyChild = persons.stream().
                anyMatch(p -> p.getAge() < 12);
        System.out.println("Any child? " + isThereAnyChild);


        //无匹配
        boolean isThereNo = persons.stream().
                noneMatch(p -> p.getAge() > 80);
        System.out.println("Any 80? " + isThereNo);
    }


    @Test
    public void demo19(){
        //1.
        Stream.generate(()->{
            double random = Math.random();
            DecimalFormat df = new DecimalFormat("0.00");
            random = Double.parseDouble(df.format(random));
            return random;
        }).limit(5).forEach(System.out::println);

        //2.
        Stream.generate(Math::random).limit(5).forEach(System.out::println);
    }



    ///////////////////【进阶:自己生成流】/////////////////////////////////




    ///////////////////【进阶:用 Collectors 来进行 reduction 操作】/////////////////////////////////


}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值