Java8(stream详解)

流的操作过程

流的创建->流的中间操作->终止操作

一、流的创建

1.通过collection系列集合提供的stream()方法或parallelStream()方法创建流

示例代码:

List<String> list = new ArrayList<>();
Stream<String> stream = list.stream();

2.通过Arrays的静态方法stream()方法产生数组流。

示例代码:

SysDeptEntity[] deptEntities = new SysDeptEntity[10];
Stream<SysDeptEntity> stream1 = Arrays.stream(deptEntities);

3.通过Stream类中的静态方法of()生成

示例代码:
Stream<String> stream2 = Stream.of("aa","bb","cc");

4.无限流的创建

1)通过迭代的方式创建

示例:

//迭代方式
         Stream stream3 = Stream.iterate(0,(x)-> x+2);
         stream3.limit(8).forEach(System.out::println);

2)通过生成的方式创建

//生成
Stream.generate(()-> {
     return new Random().nextLong();
}).limit(10).forEach(System.out::println);

二、流的中间操作

1.筛选与切片

filter (接收Lambda ,从中排除某些元素)

示例:

List<EntityTest> deptList = Arrays.asList(new EntityTest("123",23),
                new EntityTest("111",22),
                new EntityTest("111",21),
                new EntityTest("111",25),
                new EntityTest("111",24));

        deptList.stream().filter((EntityTest)-> EntityTest.getName().equals("111"))
                .forEach(System.out::println);

distinct()、limit(long MaxSize)、skip(long n)方法比较简单此处不做详细解释,见下图。

2.映射

       所谓映射是指将元素转换成其他形式或提取信息。接受一个函数作为参数,改函数会被应用到每个flatMap-接受一个函数作为参数,将流中的每个值都转换成另一个流,然后把所有流连接成一个流。

1).map映射
map方法接收一个函数作为函数,该函数会被应用到每个元素上,并将其映射成一个新的元素。
下面实例,把每个字符串转换成大写字母,把所有的序列组成一个流

    @Test
    public void test4(){
        List<String> list = Arrays.asList("aaa", "bbb", "ccc");
        /*map方法中接收一个Function类型的对象,该对象用Lambda表达式实现,输入一个字符串类型,返回一个字符串类型,并把返回的字符串放到流中*/
        Stream<String> stream = list.stream()
                                    .map((x) -> {
                                        String s = x.toUpperCase();
                                        return s;
                                    });
        stream.forEach(System.out::println);
    }

2)flatMap映射
上面一个实例,把每个子流放入一个流中,相当于流中嵌套了一个流,如果用flatMap方法的话,会把每个子流中的元素组成一个流,然后遍历一个流就可以了,而不是遍历一个流中的每个流。

    public static Stream<Character> filterString(String str){
        List<Character> list = new ArrayList<Character>();
        for(Character ch : str.toCharArray()){  //char[]
            list.add(Character.toUpperCase(ch));
        }
        return list.stream();
    }

    @Test
    public void test6(){
        List<String> list = Arrays.asList("aaa", "bbb", "ccc");
        Stream<Character> stream = list.stream()
            .flatMap(TestStream::filterString);
        stream.forEach(System.out::println);
    }

注意:map与flatMap的区别类似于集合中的add方法与addAll方法的区别,map方法映射时会将流对象一并映射过来,flatMap映射时不会映射流对象,只映射流对象中的元素。

3.排序

1).sorted()自然排序(Comparable)

 

List<EntityTest> deptList = Arrays.asList(new EntityTest("123",23),
                new EntityTest("111",22),
                new EntityTest("111",21),
                new EntityTest("111",25),
                new EntityTest("111",24));

        deptList.stream().sorted()
                .forEach(System.out::println);

2).sorted(Comparator com)定制排序(Comparator)

定制化排序的入参为函数式接口Comparator对象,关于函数式接口的介绍可参考https://blog.csdn.net/qq_41471057/article/details/102094614

默认按年龄大小排序当年龄一样时按姓名排序

List<EntityTest> deptList = Arrays.asList(new EntityTest("123",23),
                new EntityTest("2352",22),
                new EntityTest("168",21),
                new EntityTest("7654",25),
                new EntityTest("234",24));

        deptList.stream().sorted((e1,e2)->{
            if(e1.getAge()==e2.getAge()) {
                return e1.getName().compareTo(e2.getName());
            }else{
                return e1.getAge().compareTo(e2.getAge());
            }
        }).forEach(System.out::println);

4.查找与匹配(终止操作)

count()返回流中元素的总个数

max()返回流中最大值

min()返回流中最小值

还有最常用的foreach()流内部遍历

5.规约与收集

1)规约

方法名描述
reduce(T iden, BinaryOperator b)可以将流中元素反复结合起来,得到一个值。返回T
reduce(BinaryOperator b)可以将流中元素反复结合起来,得到一个值。返回Optional

代码示例:

@Test
public void test11() {
    List<Integer> llist = Arrays.asList( 1,2,3,4,5,6,7,8 );

    //这种不可能为空
    Integer sun = llist.stream()
            //首先把0作为x  然后0+1得到1  然后把1作为x  然后1+2  逐渐结合
            .reduce( 0,(x,y) -> x+y );
    System.out.println(sun);



    //这种可能为空,因为没有起始值
   Optional<Integer> ss =  list.stream()
            .map((x) -> x.getId()  )
            .reduce((x,y) -> x+y);
   System.out.println(ss.get());
}

2)收集

对流中元素执行一个可变汇聚操作。是一个终止操作。比如:将流中的元素放入到一个List集合当中,将流中的元素进行分组、分区,求和等等操作。接受一个收集器Collector对象。

收集器Collector概述

Collector是一接口。通过上面的介绍我们知道Stream的collect方法会接受一个Collector类型的参数,用来进行汇聚操作。那么是怎样实现汇聚操作的呢?Collector这个接口又有什么用呢?下面讲逐一介绍。

Collector接口

通过读Jdk的文档可以知道,Collector接口是用来定义一个可变的汇聚操作:讲输入元素累加到一个可变结果容器,当所有的输入元素都被处理过后,选择性的将累加结果转换为一个最终会的表示。汇聚操作可以被串行和并行的执行。

代码示例:

/**
 * 收集
 * collect - 将流转化为其他形式,接受一个Collector接口的实现,用于给Stream中元素做汇总的方法
 */
@Test
public void test12() {

    /**
     * Collector接口中方法的实现决定了如何对流执行收集操作,(如收集到List,Set,Map)
     * 但是Collectors实用类提供了很多静态方法,可以方便的创建常见收集器实例
     */
    List l = list.stream()
            .map( (x) -> x.getName() )
            /**将得到的name放在list*/
            .collect( Collectors.toList() );
    l.forEach( System.out::println );



    list.stream()
            .map( (x) -> x.getName() )
            /**将得到的name放在set*/
            .collect( Collectors.toSet() );


    list.stream()
            .map( (x) -> x.getName() )
            /**将得到的name放在HashSet*/
            .collect( Collectors.toCollection( HashSet::new ) );





     Long l1 = list.stream()
                     /***得到集合的总数*/
                    .collect( Collectors.counting() );
     System.out.println(l1);


    Double d = list.stream()
                    /**id的平均值*/
                     .collect( Collectors.averagingDouble( Use::getId) );



    Double d1 = list.stream()
                     /**id的总和*/
                     .collect( Collectors.summingDouble(  Use::getId ) );



    Optional optional =  list.stream()
                         /**id的最大值*/
                        .collect( Collectors.maxBy((x,y) -> Double.compare( x.getId(),y.getId() )  ) );

     System.out.println( optional.get() );

                        /**id的最小值*/
     Optional<Integer> oo = list.stream( )
             .map( Use::getSaler ).min( Double::compare );
     System.out.println(oo.get());


    /**
     * 分组
     *
     * 按照id分组
     */
    Map <Integer, List <Use>> m = list.stream()
            .collect( Collectors.groupingBy( Use::getId ) );

    //遍历map
    for (Map.Entry map:m.entrySet()) {
        System.out.println(map.getKey());
        System.out.println(map.getValue());
    }
    System.out.println(m);


    /**
     * 组合分组
     * 满足条件一个区(true),不满足条件一个区(false)
     */
    Map<String, Map<Integer, List<Use>>> mapMap = list.stream()
          .collect( Collectors.groupingBy( Use::getName,Collectors.groupingBy( (e) -> e.getId() ) ) );


    /**
     * 分区
     */
    Map<Boolean, List<Use>> map =  list.stream()
            .collect( Collectors.partitioningBy( (e) -> e.getId()>3 ) );
    System.out.println(map);



    DoubleSummaryStatistics dd = list.stream()
            .collect( Collectors.summarizingDouble( (x) -> x.getId() ) );


    /**
     * 连接字符串
     */
    list.stream()
            .map( (x) -> x.getName() )
            .collect( Collectors.joining("z") );
    

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值