Java8实战 阅读笔记

来源:互联网 发布:php输出js代码 编辑:程序博客网 时间:2024/05/18 08:03

lambda

  1. 组成

    Comparator<Apple> byWeight =(Apple a1, Apple a2) -> a1.getWeight().compareTo(a2.getWeight());Lambda表达式由参数、箭头和主体组成
  2. 示例

     使用案例             Lambda示例布尔表达式           (List<String> list) -> list.isEmpty()创建对象             () -> new Apple(10)消费一个对象         (Apple a) -> {                            System.out.println(a.getWeight());                            }从一个对象中选择/抽取  (String s) -> s.length()组合两个值            (int a, int b) -> a * b比较两个对象          (Apple a1, Apple a2) ->a1.getWeight().compareTo(a2.getWeight())
  3. 常用的函数式接口

    函数式接口           函数描述符Predicate<T>        T->booleanConsumer<T>         T->voidFunction<T,R>       T->RSupplier<T>         ()->TUnaryOperator<T>    T->TBinaryOperator<T>   (T,T)->TBiPredicate<L,R>    (L,R)->boolean BiConsumer<T,U>     (T,U)->voidBiFunction<T,U,R>   (T,U)->R
  4. Lambdas及函数式接口的例子

    布尔表达式(List<String> list) -> list.isEmpty()           Predicate<List<String>>创建对象() -> new Apple(10)                             Supplier<Apple>消费一个对象(Apple a) ->System.out.println(a.getWeight())   Consumer<Apple>从一个对象中选择/提取(String s) -> s.length()                        Function<String, Integer> 或ToIntFunction<String>合并两个值(int a, int b) -> a * b                         IntBinaryOperator比较两个对象(Apple a1, Apple a2) ->a1.getWeight().compareTo(a2.getWeight())        Comparator<Apple> 或BiFunction<Apple, Apple, Integer>或 ToIntBiFunction<Apple, Apple>

1.流简介

List<String> names=munu.stream()                      //集合流                    .filter(d->d.getCalories()>300)   //筛选热量大于300的                      .map(d->d.getName())                  //提取菜单的名字                    .limit(3)                         //取前3个                    .collect(toList());               //将流转换为List

2.中间操作

filter      中间       T->booleanmap         中间       T->Rlimit       中间       取流前n个元素,是否有序取决于所取流是否有序 skip        中间       返回一个扔掉前n个元素的流;如果流中元素不足n个,则返回一个空流    sorted      中间       (T,T)->intdistinct    中间       去重flatMap     中间       把流中的每个值都换成另一个流,然后把所有的流连接起来成为一个流forEach     终端       消费流中的每个元素并对其应用Lanbda。这一操作返回voidcount       终端       返回流中元素的个数。这一操作返回longcollect     终端       把流归约成一个集合,比如List、Map甚至是IntegerallMatch    终端       T->booleananyMatch    终端       T->booleannoneMatch   终端       T->booleanfindFirst   终端       T->OptionnalfindAny     终端       T->Optionnalreduce      终端       (T,T)->T

3.构建流

  1. 由值创建流

    Stream.of(“123”,”456”);

  2. 由数组创建流

    Arrays.stream(…);

  3. 由文件生成流

    long uniqueWords = 0;

    try(
    Stream lines =Files.lines(Paths.get(“data.txt”),Charset.defaultCharset())){
    uniqueWords = lines.flatMap(line -> Arrays.stream(line.split(” “)))
    .distinct()
    .count();
    }catch(IOException e){
    }

  4. 由函数生成流:创造无限流

    Stream API提供了两个静态方法来从函数生成流: Stream.iterate 和 Stream.generate 。

    1. iterate 方法接受一个初始值(在这里是 0 ),还有一个依次应用在每个产生的新值上的Lambda

      Stream.iterate(0, n -> n + 2)
      .limit(10)
      .forEach(System.out::println);

    2. 与 iterate 方法类似, generate 方法也可让你按需生成一个无限流

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

用流收集数据

  1. 分组:…collect(groupingBy(…))
  2. 计数:…collect(counting()) 或 menu.stream().count();
  3. 最大值和最小值:…collect(maxBy(…))和…collect(minBy(…))
  4. 汇总:…collect(summingInt())
  5. 求和:…collect(averagingInt())
  6. 连接字符串:…collect(joining())
  7. 分区:…collect(partitioningBy(…))

并行数据处理与性能

  1. 调用 parallel 方法将顺序流转换为并行流

    public static long parallelSum(long n) {
    return Stream.iterate(1L, i -> i + 1)
    .limit(n)
    .parallel()
    .reduce(0L, Long::sum);
    }

  2. 并行与顺序间切换

    stream.parallel()
    .filter(…)
    .sequential()
    .map(…)
    .parallel()
    .reduce();

  3. 正确使用并行流

    1. 留意装箱
    2. 有些操作本身在并行流上的性能就比顺序流差。特别是 limit 和 findFirst 等依赖于元素顺序的操作,它们在并行流上执行的代价非常大。
    3. 对于较小的数据量,选择并行流几乎从来都不是一个好的决定
    4. 要考虑流背后的数据结构是否易于分解。例如, ArrayList 的拆分效率比 LinkedList高得多,因为前者用不着遍历就可以平均拆分,而后者则必须遍历。
    5. 流自身的特点

默认方法

对库开发者重要,接口中新增方法,提供默认实现。之前实现了该接口的用户 不用修改 实现了该接口的类,以便接口可平滑过渡。为避免冲突,有同名方法,它会优先使用类内方法,然后是更具体的接口默认方法,或者显式调用

原创粉丝点击