阅读Java8实战后的一些笔记

1. 行为参数化

  • 定义一个接口,对选择建模
    >
    > public interface ApplePredicate{
    boolean test(Apple apple);
    }

  • **定义一个类

  • 实现该接口** > public class AppleRedAndHeavyPredicate implements ApplePredicate{
    public boolean test(Apple apple){
    return “red”.equals(apple.getColor())
    && apple.getWeight() > 150;
    }
    }

  • 使用匿名内部类简化代码 >
    List redApples = filterApples(apples,new ApplePredicate(){ public boolean test(Apple a){ return “red”.equals(a.getColor()); } });

  • 使用Lamba表达式简化 >
    List redApples = filterApples(apples,a->“red”.equals(a.getColor()));

  • 使用泛型,抽象化代码 >
    public interface Predicate{
    boolean test(T t);
    } > public static List filter(List list,Predicate p){ List result = new ArrayList<>(); for(T e:list){ if(p.test(e)){ result.add(e); } } return result; }


2. lamba表达式

  • 函数式接口
函数式接口函数描述原始类型特化
Predicate< T>T->booleanIntPredicate,
LongPredicate,
DoublePredicate
Consumer< T>T->voidIntConsumer,
LongConsumer,
DoubleConsumer
Function< T,R>T->RIntFunction< R>,
IntToDoubleFunction,
IntToLongFunction,
LongFunction< R>,
LongToDoubleFunction,
LongToIntFunction,
DoubleFunction< R>,
ToIntFunction< T>,
ToDoubleFunction< T>,
ToLongFunction< T>
Supplier()->TBooleanSupplier,
IntSupplier,
LongSupplier,
DoubleSupplier
UnaryOperatorT->TIntUnaryOperator,
LongUnaryOperator,
DoubleUnaryOperator
BinaryOperator(T,T)->TIntBinaryOperator,
LongBinaryOperator,
DoubleBinaryOperator
BiPredicate< L,R>(L,R)->boolean
BiConsumer< T,U>(T,U)->voidObjIntConsumer< T>,
ObjLongConsumer< T>,
ObjDoubleConsumer< T>
BiFunction< T,U,R>(T,U)->RToIntBiFunction< T,U>,
ToLongBiFunction< T,U>,
ToDoubleBiFunction< T,U>
  • Lambdas 及函数式接口的例子
使用案例Lambda的例子对应的函数式接口
布尔表达式(List< string>list)->list.isEmpty()Predicate>
创建对象()->new Apple(10)Supplier< apple>
消费一个对象(Apple a)->System.out.println(a.getWeight())Consumer< apple>
从一个对象中选择/提取(String s)->s.length()Function< String,Integer>,
ToIntFunction
合并两个值(int a,int b)->a*bIntBinaryOperator
比较两个对象(Apple a1,Apple a2)->
a1.getWeight().compareTo(a2.getWeight())
Comparator< apple>,
BiFunction< Apple,Apple,Integer>,
ToIntBiFunction< Apple,Apple>
  • Lambda及其等效的方法引用
    Lambda等效的引用方法
    (Apple a) -> a.getWeight()Apple::getWeight
    ()->Thread.currentThread().dumpStack()Thread.currentThread()::dumpStack
    (str,i) -> str.substring(i)String::substring
    (String s)->System.out.println(s)System.out::println

3.构造函数引用

  • 默认方法的构造函数引用 > Supplier appleSupplier = Apple::new; Supplier appleSupplier = ()->new Apple(); Apple a = appleSupplier.get();

  • 1个参数的构造函数引用
    如果函数签名类似于Apple(Integer weight)
    > Function appleFunction = Apple::new;
    Function appleFunction = (weight)->new Apple(weight);
    Apple a = appleFunction.apply(10);

  • 2个参数的构造函数引用
    如果函数签名类似于Apple(Integer weight,String color)
    > BiFunction appleBiFunction = Apple::new;
    BiFunction appleBiFunction = (weight,color)->new Apple (weight,color);
    Apple a = appleFunction.apply(10.“red”);

  • 比较器复合 > Comparator c = Comparator.comparing(Apple::getWeighjt);

    apples.sort((a,b)->a.getWeight().compareTo(b.getWeight())); 可有化成(idea会自动帮我们优化) apples.sort(Comparator.comparing(Apple::getWeight));

  • 逆序 > Comparator c = Comparator.comparing(Apple::getWeighjt) .reversed();

  • 比较链接 先按照重量排序,然后按照颜色排序 > Comparator c = Comparator.comparing(Apple::getWeighjt) .reversed() .thenComparing(Apple::getColor);

  • 谓词复合

    谓词接口包含3个方法:negate,and,or > Predicate redApple = (Apple a)->“red”.equals(a.getColor()); Predicate heaveyApple = a->a.getWeight()>150; Predicate notRedApple = redApple.negate(); Predicate redAndHeavyApple = redApple.and(heavyApple);

  • 函数复合

    谓词接口包含3个方法:negate,and,or > Function f = (a)->a*2; Function g = (b)->b+2; f.andThen(g) == g(f(x)) f.compose(g) == f(g(x)) 用此种方法可以组合成流水线工作,最后得出结果


4. 使用流

  • distinct()
    返回不重复的元素 如果是对象去重,可使用map的特效去重
  • limit(3)
    截断流,只选择前3个
  • skip(3)
    跳过流,跳过前3个
  • map() 映射
  • flatMap() 流扁平化,将各个生成的流扁平化为单个流
    例如存在
    List a = [“1”,“2”,“3”];
    List b = [“a”,“b”]; 如何生成[“1a”,“1b”,“2a”,“2b”,“3a”,“3b”]? >
  • A.
    Stream> result = a.stream().map(i->b.stream(j->return (i+j)));
    Stream s1 = [“1a”,“1b”]转换成的流;
    Stream s2 = [“2a”,“2b”]转换成的流;
    Stream s3 = [“3a”,“3b”]转换成的流;
    对result进行收集会得到[[“1a”,“1b”],[“2a”,“2b”],[“3a”,“3b”]]不符合预期
    >
  • B. Stream result = a.stream().flatMap(i->b.stream(j->return (i+j)));
    对result进行收集会得到[“1a”,“1b”,“2a”,“2b”,“3a”,“3b”]符合预期

  • anyMatch()
    流中是否存在一个元素能够匹配 返回一个boolean值

  • allMatch()
    流中是否所有元素都能够匹配 返回一个boolean值

  • nonMatch()
    流中是否所有元素都不能匹配 返回一个boolean值

  • findAny()
    流中只要找到一个匹配的元素就短路并返回一个Optional值,如果不关心顺序,请用findAny

  • findFirst()
    顺序流中只要找到一个匹配的元素就短路并返回一个Optional值,关心顺序时使用

  • isPresent()
    Optional中包含值返回true,否则返回false

  • ifPresent(Consumer block)
    会在值存在时执行消费操作代码块

  • T orElse(T other)
    会在值存在时返回值,否则返回默认值

  • reduce() int sum = list.stream().reduce(0,(a,b)->(a+b));初始为0的元素求和
    int sum = list.stream().reduce(0,Integer::sum);
    int multi = list.stream().reduce(1,(a,b)->a*b);初始为1的元素求积
    Optional multi = list.stream().reduce((a,b)->a*b);没有初始值的的元素求积将返回optional

  • 数值范围 range(),rangeClosed()
    IntStream.range(1,100) = [1,100}
    IntStream.rangeClosed(1,100) = [1,100]

  • 用Iterate创建无限流 例如:Stream.iterate(0,n->n+2).limit(5)

  • 用generate创建无限流 generate接受一个Supplier 提供新的值
    例如:Stream.generate(Math::random).limit(5);

    3.1 流收集数据

  • 总量 > Stream.of(“1”.“2”).count();
    或者 Stream.of(“1”.“2”).collect(Collectors.counting());

  • MAX 和MIN 最大的苹果: > Comparator appleComparator = Comparator.comparingInt(Apple::getWeight); Optional maxWeightApple = apples.stream().collect(Collectors.maxBy(appleComparator)); 最小值用Collectors.minBy()
    Int求和用Collectors.summarizingInt()
    Double求和用Collectors.summarizingDouble()
    Long求和用Collectors.summarizingLong()

  • 规约reduce()
    > apples.stream().collect(Collectors.reducing(0,Apple::getWeight,Integer::sum));
    apples.stream().coll ect(Collectors.reducing(0,Apple::getWeight,(i,j)->(i+j)));
    这两条代码是等价的 0 <–初始值
    Apple::getWeight <–转换函数
    (i,j)->(i+j) <–BinaryOperator

  • 分组groupingBy()
    多级分组
    > apples.stream().collect(Collectors.groupingBy(Apple::getWeight, Collectors.groupingBy(Apple::getColor)));

  • 分区partitioningBy()
    分区是分组的特殊情况,会返回Map>类型,true是以组,false是一组

  • Collectors类的静态方法

    工厂方法 返回类型 用于 示例
    toList List<T> 把流中所有项目收集到一个List List<Dish> dishes = menuStream. collect(toList());
    toSet Set<T> 把流中所有项目收集到一个Set,删除重复项 Set<Dish> dishes = menuStream. collect (toSet());
    toCollection Collection<T> 把流中所有项目收集到给定的供应源创建的集合 Collection<Dish> dishes = menuStream.collect (toCollection() ,ArrayList::new);
    counting Long 计算流中元素的个数 long howManyDishes = menuStream.collect (counting());
    summingInt Integer 对流中项目的一个整数属性求和 int totalCalories =menuStream.collect(summingInt (Dish::getCalories) );
    averagingInt Double 计算流中项目Integer属性的平均值 double avgCalories =menuStream.collect(averagingInt(Dish::getCalories));
    summarizingInt IntSummaryStatistics 收集美于流中項目Integer 属性的統竍値,例如最大、最小、总和与平均値 IntSummaryStatistics menuStatistics =menuStream.collect(summarizingInt(Dish::getCalories));
    joining String 连接对流中毎个項目调用toString方法所生成的字符串 String shortMenu =menuStream.map(Dish::getName).collect (joining(", "));
    maxBy Optional<T> 一个包裹了流中按照给定比较器选出的最大元素的Optional,或如果流为空则为optional.empty() Optional<Dish> fattest = menuStream.collect(maxBy(comparingInt(Dish::getCalories)));
    minBy Optional<T> 一个包裹了流中按照给定比较器选出的最小元素的Optional,或如果流为空则为optional.empty() Optional<Dish> lightest = menuStream.collect(minBy(comparingInt(Dish::getCalories)));
    reducing 归约操作产生的类型 从一个作为累加器的初始値幵始,利用BinaryOperator与流中的元素逐个结合,从而将流归约为单个值 int totalCalories =menuStream.collect(reducing(0,Dish::getCalories, Integer::sum));
    collectingAndThen 转换函数的类型 包裹另一个收集器,对其结果应用转换函数 int howManyDishes =menuStream.collect(collectingAndThen(toList(), List::size));
    groupingBy Map<K, List<T>> 根据项目的一个属性的值对流中的项目作问组,并将属性值作为结果Map的键 Map<Dish.Type,List<Dish>> dishesByType = menuStream.collect(groupingBy(Dish::getType));
    mapping 是一个收集器,可以传入两个函数, 一个函数对流中的元素做变换,另一个则将变换的结果对象收集起来 ,目的是在累加之前对每个元素应用一个映射函数 Map<Dish.Type, Set<CaloricLevel>> caloricLevelsByType =menu.stream().collect(groupingBy(Dish::getType, mapping(dish -> { if (dish.getCalories() <=400) return CaloricLevel.DIET;else if (dish.getCalories() <= 700) return CaloricLevel.NORMAL;else return CaloricLevel.FAT; },toSet() )));
    partitioningBy Map<Boolean, List<T> > 相据对流由每个项目应田谓词的结里求对项目经行分区 Map<Boolean, List<Dish>> vegetarianDishes =menuStream. collect (partitioningBy (Dish::isVegetarian) ) ;

待办事项

4.3 并行数据处理与性能

prallelStream()
parallel()将顺序流变为并行流
sequential()将并行流变为顺序流
自动装箱拆箱会大大降低并行流性能,此时应使用IntStream等原始类型流来避免这种操作。

5. 设计模式使用

使用lambda重构设计模式使用

4.1策略模式

待办事项


6. 默认方法


6. Optional


optional方法

序号 方法 & 描述
1 static Optional empty(); 返回空的 Optional 实例。
2 boolean equals(Object obj) 判断其他对象是否等于 Optional。
3 Optional filter(Predicate<? super predicate) 如果值存在,并且这个值匹配给定的 predicate,返回一个Optional用以描述这个值,否则返回一个空的Optional。
4 Optional flatMap(Function<? super T,Optional> mapper)如果值存在,返回基于Optional包含的映射方法的值,否则返回一个空的Optional
5 T get() 如果在这个Optional中包含这个值,返回值,否则抛出异常:NoSuchElementException
6 int hashCode() 返回存在值的哈希码,如果值不存在 返回 0。
7 void ifPresent(Consumer<? super T> consumer) 如果值存在则使用该值调用 consumer , 否则不做任何事情。
8 boolean isPresent() 如果值存在则方法会返回true,否则返回 false。
9 Optional map(Function<? super T,? extends U> mapper) 如果有值,则对其执行调用映射函数得到返回值。如果返回值不为 null,则创建包含映射返回值的Optional作为map方法返回值,否则返回空Optional。
19 static Optional of(T value) 返回一个指定非null值的Optional。
11 static Optional ofNullable(T value) 如果为非空,返回 Optional 描述的指定值,否则返回空的 Optional。
12 T orElse(T other) 如果存在该值,返回值, 否则返回 other。
13 T orElseGet(Supplier<? extends T> other) 如果存在该值,返回值, 否则触发 other,并返回 other 调用的结果。
14 T orElseThrow(Supplier<? extends X> exceptionSupplier) 如果存在该值,返回包含的值,否则抛出由 Supplier 继承的异常
15 String toString() 返回一个Optional的非空字符串,用来调试

8. CompletableFuture:组合式异步编程


9. 新的日期和时间API

9.1 LocalDate

9.2 LocalDateTime

9.3 Instant

9.4 Duration

9.5 Period