Java SE JDK8 之 stream流详解


概念:

Stream是JDK8 API的新成员,它允许以声明性方式处理数据集合 。

特点:

(1)代码简洁:函数式编程写出的代码简洁且意图明确,使用stream接口让你从此告别for循环。
(2)多核友好:Java函数式编程使得编写并行程序从未如此简单,你需要的全部就是调用一下方法。

流的生命周期:

       1.起始生成阶段。
  2.中间操作会逐一获取元素并进行处理。 可有可无。所有中间操作都是惰性的,因此,流在管道中流动之前,任何操作都不会产生任何影响。
  3.终端操作。通常分为 最终的消费 (foreach 之类的)和 归纳 (collect)两类。还有重要的一点就是终端操作启动了流在管道中的流动。

操作符:

两种:中间操作符、终止操作符

中间操作符:

1.fileter: 根据条件过滤集合数据:

方法含义示例
filter
       用于通过设置的条件过滤出元素
List strings = Arrays.asList(“abc”, “”, “bc”, “efg”, “abcd”,"", “jkl”);
List filtered = strings.stream().filter(string -> !string.isEmpty()).collect(Collectors.toList());

根据相应业务需求来过滤此集合

/**
     * 功能描述:根据条件过滤集合数据
     *
     * @return : void
     */
    @Test
    public void fileterTest() {

        List<Object> listInt = new ArrayList();//新建个int型集合
        //添加参数
        listInt.add(1);
        listInt.add(2);
        listInt.add(0);
        listInt.add(4);
        listInt.add(3);
        //获取此集合的stream流
        Stream<Object> stream = listInt.stream();

        //问题:获取大于等于1且小于等与3的数并遍历
        stream.filter(integer -> (Integer) integer >= 1).filter(integer -> (Integer) integer <= 3).forEach(integer -> System.out.println(integer));
        /*
        答案:
        * 1
        * 2
        * 3
        * */
    }



2.distinct:去除集合中重复数据:

方法含义示例
distinct
       返回一个元素各异(根据流所生成元素的hashCode和equals方法实现)的流。
List numbers = Arrays.asList(1, 2, 1, 3, 3, 2, 4);
numbers.stream().filter(i -> i % 2 == 0).distinct().forEach(System.out::println);

首先创建JavaBean对象(用来做删除重复对象测试):必须重写equles()and hasCode()[如果不重写,就会按照Object的来 Object的比较方式是 ‘==’ 比较地址的]

import java.util.Objects;

public class User {
    private String name;
    private int age;


    public User(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

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

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        User user = (User) o;
        return age == user.age &&
                Objects.equals(name, user.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, age);
    }
}


功能描述:去除泛型为对象的集合中重复数据


  /**
     * 功能描述:去除集合中重复数据
     *
     * @return : void
     */
    @Test
    public void distinctTest() {
        //首先创建出测试对象
        User userWhite = new User("小白", 12);
        User userWhite2 = new User("小白", 12);
        User useBlack = new User("小黑", 12);
        //创建集合
        List<User> userList = new ArrayList<>();
        //为集合添加测试数据
        userList.add(userWhite);
        userList.add(userWhite2);
        userList.add(useBlack);
        //获取stream流
        Stream<User> stream = userList.stream();
        //问题:去掉此集合的重复对象并遍历(这里注意集合里的User对象必须重写equles()and hasCode()[如果不重写,就会按照Object的来 Object的比较方式是 '==' 比较地址的])
        stream.distinct().forEach(user -> System.out.println(user));
        /*
         *答案:
         * User{name='小白', age=12}
         * User{name='小黑', age=12}
         * */
    }



3.limit:指定获取集合前x条数据,重新构造一个新的集合:

方法含义示例
limit
       会返回一个不超过给定长度的流。
List strings = Arrays.asList(“abc”, “abc”, “bc”, “efg”, “abcd”,“jkl”, “jkl”);
List limited = strings.stream().limit(3).collect(Collectors.toList());

指定获取此集合前几条数据(指定数值可大于此集合数据个数:大于此集合个数则返回此集合所有数据)

 /**
     * 功能描述:指定获取集合前x条数据,重新构造一个新的集合
     *
     * @return : void
     */
    @Test
    public void limitTest() {
        //创建集合
        List<String> stringList = new ArrayList<>();
        //创建测试参数
        String ab = "ab";
        String cd = "cd";
        String ef = "ef";
        String gh = "gh";
        //为集合添加测试数据
        stringList.add(ab);
        stringList.add(cd);
        stringList.add(ef);
        stringList.add(gh);
        //获取此集合的stream流
        Stream<String> stream = stringList.stream();

        //问题:获取此集合前两个参数并遍历
        stream.limit(2).forEach(string -> System.out.println(string));
        /*
         * 答案:
         * ab
         * cd
         * */
    }



4.skip:排除集合前x条数据,把后面的数据重新构造一个新的集合:

方法含义示例
skip
       返回一个扔掉了前n个元素的流。
List strings = Arrays.asList(“abc”, “abc”, “bc”, “efg”, “abcd”,“jkl”, “jkl”);
List skiped = strings.stream().skip(3).collect(Collectors.toList());

排除集合前x条数据,获取此集合后面的所有数据

/**
     * 功能描述:排除集合前x条数据,把后面的数据重新构造一个新的集合
     *
     * @return : void
     */
    @Test
    public void skipTest() {
        //通过Arrays.asList方法 可以把数组转为List集合
        List<Integer> integerList = Arrays.asList(1, 2, 3, 4);
        //获取此集合的stream流
        Stream<Integer> stream = integerList.stream();
        //问题:排除此集合前两个参数,获取后面的所有参数
        stream.skip(2).forEach(integer -> System.out.println(integer));
        /*
         * 答案:
         * 3
         * 4
         * */
    }


5.map:对集合中所有元素统一处理

方法含义示例
map
       接受一个函数作为参数。这个函数会被应用到每个元素上,并将其映射成一个新的元素(使用映射一词,是因为它和转换类似,但其中的细微差别在于它是“创建一个新版本”而不是去“修改”)。
List strings = Arrays.asList(“abc”, “abc”, “bc”, “efg”, “abcd”,“jkl”, “jkl”);
List skiped = strings.stream().skip(3).collect(Collectors.toList());

用于改变流中元素,无法调用方法或接口(与flatMap相似)

  /**
     * 功能描述:对集合中所有元素统一处理
     *
     * @return : void
     */
    @Test
    public void mapTest() {
        //通过Arrays.asList方法 可以把数组转为List集合
        List<String> stringList = Arrays.asList("a", "b", "c", "d");
        //获取此集合的stream流
        Stream<String> stream = stringList.stream();
        //问题:每个数据上都加一个map并遍历
        stream.map(string -> string + "map").forEach(sting -> System.out.println(sting));
        /*
         * 答案:
         * amap
         * bmap
         * cmap
         * dmap
         * */
    }



6.flatMap:对集合中所有元素统一处理:

方法含义示例
flatMap
       使用flatMap方法的效果是,各个数组并不是分别映射成一个流,而是映射成流的内容。所有使用map(Arrays::stream)时生成的单个流都被合并起来,即扁平化为一个流。
List strings = Arrays.asList(“abc”, “abc”, “bc”, “efg”, “abcd”,“jkl”, “jkl”);
Stream flatMap = strings.stream().flatMap(Java8StreamTest::getCharacterByString);

用于改变流中元素,无法调用方法或接口(与map相似)

   /**
     * 功能描述:对集合中所有元素统一处理
     *
     * @return : void
     */
    @Test
    public void flatMap() {
        //通过Arrays.asList方法 可以把数组转为List集合
        List<String> stringList = Arrays.asList("a", "b", "c", "d");
        //获取此集合的stream流
        Stream<String> stream = stringList.stream();
        //问题:每个数据上都加一个map并遍历
        stream.flatMap(s -> Arrays.asList(s + "map").stream()).forEach(s -> System.out.println(s));
        /*
         * 答案:
         * amap
         * bmap
         * cmap
         * dmap
         * */
    }


7.对比map与faltMap的区别:

map:相当于 put( ) 就是直接加进集合
faltMap:相当于 putAll( ) 将集合拆开再一个个加进另一个集合

	 /**
     * 功能描述:对比map与faltMap的区别
     * map:相当于 put 就是直接加进集合
     * faltMap:相当于 putAll 将集合拆开再一个个加进另一个集合
     *
     * @return : void
     */
    @Test
    public void mapEqulesFlatMap() {
        //先创建测试参数
        List<String> stringList = Arrays.asList("a.a", "b.b", "c.c","d");
        //这里map(s->s.split("\\."))收集之后的结果是Stream<String[]>
        stringList.stream().map(s -> s.split("\\.")).forEach(s -> System.out.println(Arrays.toString(s)));
        /*
         * 打印结果:
         * [a, a]
         * [b, b]
         * [c, c]
         * [d]
         * */
        //这里map(s->s.split("\\."))收集之后的结果是Stream<String>
        stringList.stream().flatMap(s -> Arrays.stream(s.split("\\."))).forEach(s -> System.out.println(s));
        /*
         * 打印结果:
         * a
         * a
         * b
         * b
         * c
         * c
         * d
         * */
    }


8.peek: 用于不改变流中元素本身 而调用接口或者方法用于传参:

方法含义示例
peek
       用于不改变流中元素本身 而调用接口或者方法用于传参
List stringList = Arrays.asList(“a”,“b”,“c”,“d”);
stringList.stream().peek(s -> System.out.println(s)).count();

peek为中间操作符,所以必须要有终止符才会运行相应操做
peek :此方法只能用于把集合内的所有元素当作入参对象来调用别的方法,且无法改变元素本身

 /*
    * peek为中间操作符,所以必须要有终止符才会运行相应操做
    * peek :用于不改变流中元素本身 而调用接口或者方法用于传参
    * */
    @Test
    public void peekTest(){
        List<String> stringList = Arrays.asList("a","b","c","d");
        //stringList.stream().peek(s -> s+"err").count(); //报错 无法改变流中元素,map可以(但map不能用来调用方法)
        stringList.stream().peek(s -> test(s)).count();
        stringList.stream().peek(s -> System.out.println(s)).count();
    }
    
	/*
    * 测试peek (调用此方法)
    * */
    public void test(String s){
        System.err.println(s+"--进入test方法");
    }



9.map与peek的区别

peek :用于不改变流中元素本身 而是把元素当作参数调用接口或方法
map 用于改变流中元素,无法调用方法或接口

  /* map与peek的区别:
     * peek为中间操作符,所以必须要有终止符才会运行相应操做
     * peek :用于不改变流中元素本身 而调用接口或者方法用于传参
     * map为中间操作符,所以必须要有终止符才会运行相应操做
     * map 用于改变流中元素,无法调用方法或接口
     * */
    @Test
    public  void  peekEqulesMapTest(){
        List<String> stringList = Arrays.asList("a","b","c","d");
        //stringList.stream().peek(s -> s+"err").count(); //报错 无法改变流中元素,map可以(但map不能调用别的方法)
        stringList.stream().peek(s -> test(s)).forEach(System.out::println);
        /*
        *   a--进入test方法
            a
            b--进入test方法
            b
            c--进入test方法
            c
            d--进入test方法
            d
        * */
        //stringList.stream().map(s -> test(s)).forEach(System.out::println); 报错 map只能改变元素,无法调用方法
        stringList.stream().map(s -> s+"map").forEach(System.out::println);
        /*
        *   amap
            bmap
            cmap
            dmap
        * */
    }
    
    /*
    * 测试peek (调用此方法)
    * */
    public void test(String s){
        System.err.println(s+"--进入test方法");
    }


10.对集合进行排序:

方法含义示例
sorted
       返回排序后的流
List strings1 = Arrays.asList(“abc”, “abd”, “aba”, “efg”, “abcd”,“jkl”, “jkl”);
List sorted1 = strings1.stream().sorted().collect(Collectors.toList());

最普通的javaBean:用来做顺序排序用的;

import java.util.Objects;

public class User {
    private String name;
    private int age;


    public User(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

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

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        User user = (User) o;
        return age == user.age &&
                Objects.equals(name, user.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, age);
    }
}

对集合中所有元素进行排序

 /**
     * 功能描述 : 对集合进行排序
     *
     * @return : void
     */
    @Test
    public void sortedTest() {
        List<Integer> integerList = Arrays.asList(1, 0, 3, 2);
        List<String> stringLetterList = Arrays.asList("abc", "bac", "acb", "cba");
        List<String> stringSimplifyList = Arrays.asList("小白", "蓝蓝", "小黑");
        List<User> userList = Arrays.asList(new User("小兰", 12), new User("小白", 11));
        System.out.println("------数字升序-------");
        integerList.stream().sorted().forEach(s -> System.out.println(s));
        System.out.println("------数字倒序-------");
        integerList.stream().sorted(Comparator.reverseOrder()).forEach(s -> System.out.println(s));
        System.out.println("------字符串升序----");
        stringLetterList.stream().sorted().forEach(s -> System.out.println(s));
        System.out.println("-----字符串倒序----");
        stringLetterList.stream().sorted(Comparator.reverseOrder()).forEach(s -> System.out.println(s));
        System.out.println("------汉字升序-------");
        stringSimplifyList.stream().sorted().forEach(s -> System.out.println(s));
        System.out.println("------汉字倒序-------");
        stringSimplifyList.stream().sorted(Comparator.reverseOrder()).forEach(s -> System.out.println(s));
        System.out.println("------按照对象年龄升序-------");
        userList.stream().sorted(Comparator.comparing(User::getAge)).forEach(user -> System.out.println(user));
        System.out.println("------按照对象年龄倒序-------");
        userList.stream().sorted(Comparator.comparing(User::getAge).reversed()).forEach(user -> System.out.println(user));

            /*------数字升序-------
                    0
                    1
                    2
                    3
            ------数字倒序-------
                    3
                    2
                    1
                    0
            ------字符串升序----
                    abc
                    acb
                    bac
                    cba
            -----字符串倒序----
                    cba
                    bac
                    acb
                    abc
            ------汉字升序-------
                    小白
                    小黑
                    蓝蓝
            ------汉字倒序-------
                    蓝蓝
                    小黑
                    小白
            ------按照对象年龄升序-------
            User{name='小白', age=11}
            User{name='小兰', age=12}
            ------按照对象年龄倒序-------
            User{name='小兰', age=12}
            User{name='小白', age=11}
            */
    }


终止操作符:

1.anyMatch: 判断集合中是否至少存在一个元素满足条件返回true:

方法含义示例
anyMatch
       检查是否至少匹配一个元素,返回boolean。
List strings = Arrays.asList(“abc”, “abd”, “aba”, “efg”, “abcd”,“jkl”, “jkl”);
boolean b = strings.stream().anyMatch(s -> s == “abc”);

检查是否至少匹配一个元素,返回boolean(只要有一个满足及返回true,否则返回false)

 /**
     * 功能描述 : 判断集合中是否至少存在一个元素满足条件返回true
     *
     * @return : void
     */
    @Test
    public void anyMatchTest() {
        //通过Arrays.asList方法 可以把字符串数组转为List集合
        List<String> stringList = Arrays.asList("a", "b", "c");
        //获取此集合的stream流并判断是否匹配到s此元素
        boolean b = stringList.stream().anyMatch(s -> "a".equals(s));
        System.out.println(b);//true[此集合有一个参数匹配到则返回true]
        //获取此集合的stream流并判断是否匹配到z此元素
        boolean z = stringList.stream().anyMatch(s -> "z".equals(s));
        System.out.println(z);//false[此集合有一个参数匹配到则返回true]
    }



2.allMatch: 判断集合中是否所有元素都满足条件:

方法含义示例
allMatch
       检查是否匹配所有元素,返回boolean。
List strings = Arrays.asList(“abc”, “abd”, “aba”, “efg”, “abcd”,“jkl”, “jkl”);
boolean b = strings.stream().allMatch(s -> s == “abc”);

allMatch:   判断集合中是否所有元素都满足条件返回true
anyMatch: 判断集合中是否至少存在一个元素满足条件返回true

/**
     * 功能描述 : 判断集合中是否所有元素都满足条件
     *
     * @return : void
     */
    @Test
    public void allMatchTest() {
        //通过Arrays.asList方法 可以将数值数组转为List集合
        List<Integer> integerList = Arrays.asList(0, 2, 4, 6);
        //通过stream流 判断此集合是否能被2整除
        boolean b = integerList.stream().allMatch(integer -> integer % 2 == 0);
        System.out.println(b);//true[当此集合所有参数都符合则返回true]
    }



3.noneMatch: 判断集合中是否所有元素都不满足条件:

方法含义示例
noneMatch
       检查是否没有匹配所有元素,返回boolean。
List strings = Arrays.asList(“abc”, “abd”, “aba”, “efg”, “abcd”,“jkl”, “jkl”);
boolean b = strings.stream().noneMatch(s -> s == “abc”);

allMatch:     判断集合中是否所有元素都满足条件返回true
anyMatch:   判断集合中是否至少存在一个元素满足条件返回true
noneMatch: 判断集合中是否所有元素都不满足条件 返回true

 /**
     * 功能描述 : 判断集合中是否所有元素都不满足条件
     *
     * @return : void
     */
    @Test
    public void noneMatchTest() {
        //通过Arrays.asList方法 可以将数值数组转为List集合
        List<Integer> integerList = Arrays.asList(1, 3, 5, 7);
        //通过stream流 判断此集合是否能被2整除
        boolean b = integerList.stream().noneMatch(integer -> integer % 2 == 0);
        System.out.println(b);//true[当此集合所有参数都不符合返回true]
    }



4.findAny:返回当前流中任意元素:

方法含义示例
findAny
       将返回当前流中的任意元素。
List strings = Arrays.asList(“cv”, “abd”, “aba”, “efg”, “abcd”,“jkl”, “jkl”);
Optional any = strings.stream().findAny();

返回当前流中任意元素 [返回的不是任意元素!(骗子)]
并行流:把一个内容分为多个数据块,并用不同的线程分别处理每个数据块的流。(返回的几乎是集合中间的元素)
串行流: 一整个数据块, 一个线程处理数据流。(返回的大部分都是第一个元素)

 /**
     * 功能描述 : 返回当前流中任意元素[返回不了!(骗子)]
     * stream:串行流:返回Stream中的第一个元素,但不保证这一点(意思就是有可能返回别的,但我循环好多次都没遇到QAQ就返回集合的第一个)。
     * parallelStream:并行流:返回的差不多以此List集合中间的那个数据为主,然后以那个中间数据左右摇摆返回数据(循环1000此 a占绝大部分(961个),剩下的就c(2个)或f(33个),然后就其他的极少极少部分(占5个))
     *
     * @return : void
     */
    @Test
    public void findAnyTest() {
        //通过Arrays.asList方法 可以将字符串数组转为List集合
        List<String> stringList = Arrays.asList("d", "f", "a", "c", "g");
        //重复1000次来测试返回元素
        for (int i = 0; i < 1000; i++) {
            //获取任意元素
            String s = stringList.parallelStream().findAny().get();
            System.out.println(s);
        }
    }

5.findFirst: 返回当前流中第一个元素

方法含义示例
findFirst
       返回第一个元素
List strings = Arrays.asList(“cv”, “abd”, “aba”, “efg”, “abcd”,“jkl”, “jkl”);
Optional first = strings.stream().findFirst();

顾名思义,返回集合中第一个元素[虽说用findAny()串行流返回的也是此集合的第一个元素,但终归是旁门左道,它主要是返回集合中的任意元素 (虽说我做测试一次 都没见过它返回过除第一个以外的元素QWQ)]

  /**
     * 功能描述 : 返回当前流中第一个元素
     *
     * @return : void
     */
    @Test
    public void findFirstTest() {
        //通过Arrays.asList方法 可以将数值数组转为List集合
        List<Integer> integerList = Arrays.asList(2, 3, 1, 0);
        //获取此集合的第一个元素的Optional容器
        Optional<Integer> first = integerList.stream().findFirst();
        //判断Optional容器里是否有参数,有则返回true
        first.ifPresent(System.out::println);
    }


6.forEach: 遍历流

方法含义示例
forEach
       遍历流
List strings = Arrays.asList(“cv”, “abd”, “aba”, “efg”, “abcd”,“jkl”, “jkl”);
strings.stream().forEach(s -> out.println(s));

就是相当于我们写的 for循环遍历
效率问题:
                如果在循环体中有复杂的业务、调用远程接口或数据库就用stream,因为stream是多线程方式并行执行,但是其调用线程池必然会消耗性能,所以简单的操作固然还是for循环效率高。

 /**
     * 功能描述 : 遍历流
     *
     * @return : void
     */
    @Test
    public void foreachTest() {
        //通过Arrays.asList方法 可以将字符串数组转为List集合
        List<String> stringList = Arrays.asList("小白", "小黑", "小兰", "小花");
        //集合遍历
        stringList.forEach(System.out::println);
        /*
        小白
        小黑
        小兰
        小花
        * */
    }



7.count: 返回流中元素总数

方法含义示例
count
       返回流中元素总数。
List strings = Arrays.asList(“cv”, “abd”, “aba”, “efg”, “abcd”,“jkl”, “jkl”);
long count = strings.stream().count();

相当于我们写的List.size()
效率问题:
                如果在获取个数中有复杂的业务、调用远程接口或数据库就用stream,因为stream是多线程方式并行执行,但是其调用线程池必然会消耗性能,所以简单的操作固然还是list.size()效率高。

/**
     * 功能描述 : 返回流中元素总数
     *
     * @return : void
     */
    @Test
    public void countTest() {
        //通过Arrays.asList方法 可以将字符串数组转为List集合
        List<Integer> integerList = Arrays.asList(0, 1, 2, 3);
        //获取此集合中元素总[integerList.size()也行](也没找到他们俩有啥区别)
        long count = integerList.stream().count();
        System.out.println(count);
    }


8.collect: 流转换为其他形式(List->Map,List<->Set):

方法含义示例
collect
       收集器,将流转换为其他形式。
List strings = Arrays.asList(“cv”, “abd”, “aba”, “efg”, “abcd”,“jkl”, “jkl”);
Set set = strings.stream().collect(Collectors.toSet());
List list = strings.stream().collect(Collectors.toList());
Map<String, String> map = strings.stream().collect(Collectors.toMap(v ->v.concat("_name"), v1 -> v1, (v1, v2) -> v1));

将类型相互转换:
                         Array–>List
                         List–>Map
                         List–>Set

 /**
     * 功能描述 : 流转换为其他形式
     *
     * @return : void
     */
    @Test
    public void collectTest() {
        System.out.println("------------------list集合----------------------------------");
        //通过Arrays.asList方法 可以将字符串数组转为List集合
        List<String> stringList = Arrays.asList("小白", "小白", "小黑", "小兰", "小花");
        //List转换为Set
        Set<String> set = stringList.stream().collect(Collectors.toSet());
        System.out.println(set);//[小白, 小黑, 小花, 小兰]
        //list转为list
        List<String> list = stringList.stream().collect(Collectors.toList());
        System.out.println(list);//[小白, 小白, 小黑, 小兰, 小花]
        //list转为Map[]
        /*
        * map传参含义
            keyMapper:Key 的映射函数
            valueMapper:Value 的映射函数
            mergeFunction:当 Key 冲突时,调用的合并方法(最主要!用于key重复时使用)
            mapSupplier:Map 构造器,在需要返回特定的 Map 时使用
        * */
        Map<String, String> map = stringList.stream().collect(Collectors.toMap(s -> s.concat("_name"), s1 -> s1, (s, s1) -> s1 + "重复", HashMap::new));
        System.out.println(map);//{小白_name=小白重复, 小黑_name=小黑, 小花_name=小花, 小兰_name=小兰}
        System.out.println("------------------set集合----------------------------------");
        //创建set集合并赋值
        Set<String> stringSet = new HashSet<String>();
        stringSet.add("劫");
        stringSet.add("烬");
        stringSet.add("亚索");
        //set转List
        List<String> setToList = stringSet.stream().collect(Collectors.toList());
        System.out.println(setToList);//[亚索, 劫, 烬]
        //set转Map(这里就不用考虑重复问题了)
        Map<String, String> setToMap = stringSet.stream().collect(Collectors.toMap(s -> s, s -> s));
        System.out.println(setToMap);//{亚索=亚索, 劫=劫, 烬=烬}
    }


9.reduce: 将流中元素反复结合起来,得到一个值:

方法含义示例
reduce
       可以将流中元素反复结合起来,得到一个值。
List strings = Arrays.asList(“cv”, “abd”, “aba”, “efg”, “abcd”,“jkl”, “jkl”);
Optional reduce = strings.stream().reduce((acc,item) -> {return acc+item;});
if(reduce.isPresent())out.println(reduce.get());

List<String>:用符号  + 即表示 把此集合的所有元素进行拼接并返回结果
List<int>: 用符号  + 即表示 数值的加法运算并返回结果
                        用符号  * 即表示数值的乘法运算并返回结果
List<Object>: 必须设置初始值 identity

/**
     * 功能描述 : 将流中元素反复结合起来,得到一个值
     * @return : void
     */
    @Test
    public void reduceTest(){
    //--------------泛型为字符串集合测试--------------------
        List<String> stringList = Arrays.asList("a","b","c");
        String s = stringList.stream().reduce((a, b) -> {
            return a + b;
        }).get();
        System.out.println(s);//abc
    //--------------泛型为int集合测试--------------------
        List<Integer> integerList = Arrays.asList(1,2,4,3);
        Integer integer1 = integerList.stream().reduce((a, b) -> {
            return a + b;
        }).get();

        System.out.println(integer1);//10
        Integer integer2 = integerList.stream().reduce(-10,(a, b) -> {
            return a + b;
        });
        System.out.println(integer2);//0
    //--------------泛型为对象集合测试--------------------
        List<User> userList = new ArrayList<>();
        userList.add(new User("小白",12));
        userList.add(new User("小黑",13));
        userList.add(new User("小倩",12));
        Integer reduce = userList.stream().reduce(Integer.valueOf(0)  /*初始值 identity*/
                , (integer, user) -> integer + user.getAge() /*累加计算 accumulator*/
                , (age1, age2) -> age1 + age2 /*第三个参数 combiner*/
        );
          System.out.println(reduce);//37
        //上面获取年龄总和 和下方代码意思一致
        Integer total=userList.stream().mapToInt(User::getAge).sum();
        System.out.println(total);//37
    }




链接:JDK8 Stream流 源代码下载地址

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

孟浩浩

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

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

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

打赏作者

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

抵扣说明:

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

余额充值