【转】java8-进阶

原文地址 http://blog.csdn.net/myherux/article/details/71855110

Java8-进阶

函数式接口

只包含一个抽象方法的接口

  • Function<T, R>

    接受一个输入参数,返回一个结果。

    Function接口包含以下方法:

    定义两个比较简单的函数:times2squared

    Function<Integer, Integer> times2 = e -> e * 2;
    Function<Integer, Integer> squared = e -> e * e;
    
    • R apply(T t)

      执行函数

      //return 8 - > 4 * 2
      Integer a = times2.apply(4);
      System.out.println(a);
      
    • compose

      先执行参数里面的操作,然后执行调用者

      //return 32 - > 4 ^ 2 * 2
      Integer b = times2.compose(squared).apply(4);
      System.out.println(b);
      
    • andThen

      先执行调用者操作,再执行参数操作

      //return 64 - > (4 * 2) ^ 2
      Integer c = times2.andThen(squared).apply(4);
      System.out.println(c);
      
    • identity

      总是返回传入的参数本身

      //return 4
      Integer d = identity.apply(4);
      System.out.println(d);
      
  • BiFunction<T, U, R>

    接受输入两个参数,返回一个结果

    • R apply(T t, U u)

      BiFunction<Integer, Integer, Integer> add = (x, y) -> x + y;
      //return 30
      System.out.println(add.apply(10,20));
      
  • Supplier<T>

    无参数,返回一个结果。

    • T get()

      Supplier<Integer> get= () -> 10;
      //return 10
      Integer a=get.get();
      
  • Consumer<T>

    代表了接受一个输入参数并且无返回的操作

    • void accept(T t)

      //return void
      Consumer<Integer> accept=x->{};
      
  • BiConsumer<T, U>

    代表了一个接受两个输入参数的操作,并且不返回任何结果

    • void accept(T t, U u)

      //return void
      BiConsumer<Integer,Integer> accept=(x,y)->{};
      
  • BinaryOperator<T> extends BiFunction<T,T,T>

    一个作用于于两个同类型操作符的操作,并且返回了操作符同类型的结果

    定义了两个静态方法:minBy,maxBy

  • Predicate<T>

    接受一个输入参数,返回一个布尔值结果。

    • test

      Predicate<String> predicate=x->x.startsWith("a");
      //return ture
      System.out.println(predicate.test("abc"));
      

Stream接口

  • Collector接口

    Collector是Stream的可变减少操作接口

    Collector<T, A, R>接受三个泛型参数,对可变减少操作的数据类型作相应限制:

    T:输入元素类型

    A:缩减操作的可变累积类型(通常隐藏为实现细节)

    R:可变减少操作的结果类型

    Collector接口声明了4个函数,这四个函数一起协调执行以将元素目累积到可变结果容器中,并且可以选择地对结果进行最终的变换:

    • Supplier<A> supplier(): 创建新的结果结
    • BiConsumer<A, T> accumulator(): 将元素添加到结果容器
    • BinaryOperator<A> combiner(): 将两个结果容器合并为一个结果容器
    • Function<A, R> finisher(): 对结果容器作相应的变换

    在Collector接口的characteristics方法内,可以对Collector声明相关约束:

    • Set<Characteristics> characteristics():

      Characteristics是Collector内的一个枚举类,声明了CONCURRENT、UNORDERED、IDENTITY_FINISH等三个属性,用来约束Collector的属性:

      • CONCURRENT:表示此收集器支持并发,意味着允许在多个线程中,累加器可以调用结果容器
      • UNORDERED:表示收集器并不按照Stream中的元素输入顺序执行
      • IDENTITY_FINISH:表示finisher实现的是识别功能,可忽略。

      如果一个容器仅声明CONCURRENT属性,而不是UNORDERED属性,那么该容器仅仅支持无序的Stream在多线程中执行。

定义自己的Stream

  • collect

    collect有两个接口:

    <R> R collect(Supplier<R> supplier,
                  BiConsumer<R, ? super T> accumulator,
                  BiConsumer<R, R> combiner);
    <R, A> R collect(Collector<? super T, A, R> collector);              
    
    • <1> <R> R collect(Supplier<R> supplier, BiConsumer<R, ? super T> accumulator, BiConsumer<R, R> combiner)

      Supplier supplier是一个工厂函数,用来生成一个新的容器;

      BiConsumer accumulator也是一个函数,用来把Stream中的元素添加到结果容器中;

      BiConsumer combiner还是一个函数,用来把中间状态的多个结果容器合并成为一个(并发的时候会用到)

      Supplier<List<String>> supplier = ArrayList::new;
      BiConsumer<List<String>, String> accumulator = List::add;
      BiConsumer<List<String>, List<String>> combiner = List::addAll;
      
      //return [aaa1, aaa1],实现了Collectors.toCollection
      List<String> list1 = stringCollection.stream()
              .filter(x -> x.startsWith("a"))
              .collect(supplier, accumulator, combiner);
      
    • <2> <R, A> R collect(Collector<? super T, A, R> collector)

      Collectors是Java已经提供好的一些工具方法:

      List<String> stringCollection = new ArrayList<>();
      stringCollection.add("ddd2");
      stringCollection.add("aaa1");
      stringCollection.add("bbb1");
      stringCollection.add("aaa1");
      

      转换成其他集合:

      • toList

        //return [aaa1, aaa1]
        stringCollection.stream()
            .filter(x -> x.startsWith("a")).collect(Collectors.toList())
        
      • toSet

        //return [aaa1]
        stringCollection.stream()
            .filter(x -> x.startsWith("a")).collect(Collectors.toSet())
        
      • toCollection

        接口:

        public static <T, C extends Collection<T>> Collector<T, ?, C> toCollection(Supplier<C> collectionFactory)
        

        实现:

        //return [aaa1, aaa1]
        List<String> list = stringCollection.stream()
            .filter(x -> x.startsWith("a"))
            .collect(Collectors.toCollection(ArrayList::new));
        
      • toMap

        接口:

        public static <T, K, U>
        Collector<T, ?, Map<K,U>> toMap(Function<? super T, ? extends K> keyMapper,
                              Function<? super T, ? extends U> valueMapper) 
        

        实现:

        //return {aaa1=aaa1_xu}
        Function<String, String> xu = x -> x + "_xu";
        Map<String, String> map = stringCollection.stream()
            .filter(x -> x.startsWith("a"))
            .distinct()
            .collect(Collectors.toMap(Function.identity(), xu));
        

      转成值:

      • averagingDouble:求平均值,Stream的元素类型为double
      • averagingInt:求平均值,Stream的元素类型为int
      • averagingLong:求平均值,Stream的元素类型为long
      • counting:Stream的元素个数
      • maxBy:在指定条件下的,Stream的最大元素
      • minBy:在指定条件下的,Stream的最小元素
      • reducing: reduce操作
      • summarizingDouble:统计Stream的数据(double)状态,其中包括count,min,max,sum和平均。
      • summarizingInt:统计Stream的数据(int)状态,其中包括count,min,max,sum和平均。
      • summarizingLong:统计Stream的数据(long)状态,其中包括count,min,max,sum和平均。
      • summingDouble:求和,Stream的元素类型为double
      • summingInt:求和,Stream的元素类型为int
      • summingLong:求和,Stream的元素类型为long

      数据分区:

      • partitioningBy

        接口:

        public static <T> Collector<T, ?, Map<Boolean, List<T>>> partitioningBy(Predicate<? super T> predicate)
        
        public static <T, D, A>
        Collector<T, ?, Map<Boolean, D>> partitioningBy(Predicate<? super T> predicate,
                                                           Collector<? super T, A, D> downstream)
        

        实现:

        Predicate<String> startA = x -> x.startsWith("a");
        //return {false=[ddd2, bbb1], true=[aaa1, aaa1]}
        Map<Boolean, List<String>> map2 = stringCollection.stream()
                .collect(Collectors.partitioningBy(startA));
        
        //return {false={false=[ddd2], true=[bbb1]}, true={false=[], true=[aaa1, aaa1]}}
        Predicate<String> end1 = x -> x.endsWith("1");
        Map<Boolean, Map<Boolean, List<String>>> map3 = stringCollection.stream()
                .collect(Collectors.partitioningBy(startA, Collectors.partitioningBy(end1)));
        

      数据分组:

      • groupingBy

        接口:

        public static <T, K> Collector<T, ?, Map<K, List<T>>> groupingBy(Function<? super T, ? extends K> classifier)
        
        public static <T, K, A, D>
        Collector<T, ?, Map<K, D>> groupingBy(Function<? super T, ? extends K> classifier,
                                        Collector<? super T, A, D> downstream)
        
        public static <T, K, D, A, M extends Map<K, D>>
        Collector<T, ?, M> groupingBy(Function<? super T, ? extends K> classifier,Supplier<M> mapFactory,
                                Collector<? super T, A, D> downstream)
        

        实现:

        //rerurn {a=[aaa1, aaa1], b=[bbb1], d=[ddd2]}
        Function<String, String> stringStart = x -> String.valueOf(x.charAt(0));
        Map<String, List<String>> map4 = stringCollection.stream()
                .collect(Collectors.groupingBy(stringStart));
        
        //rerurn {ddd2=1, bbb1=1, aaa1=2}
        Map<String, Long> map5 = stringCollection.stream()
                .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
        
        //rerurn {d=1, a=2, b=1}
        Map<String, Long> map6 = stringCollection.stream()
                .collect(Collectors.groupingBy(stringStart, LinkedHashMap::new, Collectors.counting()));
        
  • reduce

    reduce有三个接口:

    Optional<T> reduce(BinaryOperator<T> accumulator);
    
    <U> U reduce(U identity,
                 BiFunction<U, ? super T, U> accumulator,
                 BinaryOperator<U> combiner);
    
    T reduce(T identity, BinaryOperator<T> accumulator);
    
    • <1> Optional<T> reduce(BinaryOperator<T> accumulator)

      BinaryOperator<String> binaryOperator = (x, y) -> x + y;
      //rerurn ddd2aaa1bbb1aaa1
      String reduceStr1 = stringCollection.stream().reduce(binaryOperator).orElse("");
      
    • <2> T reduce(T identity, BinaryOperator<T> accumulator)

      //return start:ddd2aaa1bbb1aaa1
      String reduceStr2=stringCollection.stream().reduce("start:",binaryOperator);
      
    • <3> <U> U reduce(U identity,BiFunction<U, ? super T, U> accumulator,BinaryOperator<U> combiner)

      第一个参数返回实例u,传递你要返回的U类型对象的初始化实例u

      BiFunction accumulator,负责数据的累加

      BinaryOperator combiner,负责在并行情况下最后合并每个reduce线程的结果

      List<Person> personList = new ArrayList<>();
      personList.add(new Person(10, 20));
      personList.add(new Person(20, 30));
      personList.add(new Person(30, 50));
      
      BiFunction<Person, Person, Person> biFunction = (x, y) -> new Person(x.getAge() + y.getAge(), x.getRate() + y.getRate());
      BinaryOperator<Person> binaryOperator1 = (x, y) -> new Person(x.getAge() + y.getAge(), x.getRate() + y.getRate());
      Person total = personList.stream().reduce(new Person(0, 0), biFunction, binaryOperator1);
      System.out.println("total:"+total);
      
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,463评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,868评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,213评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,666评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,759评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,725评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,716评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,484评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,928评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,233评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,393评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,073评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,718评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,308评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,538评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,338评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,260评论 2 352

推荐阅读更多精彩内容

  • Int Double Long 设置特定的stream类型, 提高性能,增加特定的函数 无存储。stream不是一...
    patrick002阅读 1,272评论 0 0
  • Java8 in action 没有共享的可变数据,将方法和函数即代码传递给其他方法的能力就是我们平常所说的函数式...
    铁牛很铁阅读 1,227评论 1 2
  • 本文将会详细讲解Stream的使用方法(不会涉及Stream的原理,因为这个系列的文章还是一个快速学习如何使用的)...
    光剑书架上的书阅读 5,563评论 0 16
  • 参考书籍:《Java 8函数式编程》 一. 四种最基本的函数式接口 使用Stream类进行流操作之前,先了解一下四...
    纳米君阅读 6,693评论 3 8
  • 了解Stream ​ Java8中有两个最为重要的改变,一个是Lambda表达式,另一个就是Stream AP...
    龙历旗阅读 3,310评论 3 4