Lambda学习
lambda表达式,可以使得代码变得很简洁
lambda表达式,即(可省略类型,也可省略参数的参数列表)->{ 代码块 }
new Thread(new Runnable() {
@Override
public void run() {
System.out.println();
}
}).start();
new Thread(() ->System.out.println().start(););
语法格式
- (parameters) -> expression[表达式]
- (parameters) -> statements[语句]
- (parameters) ->{ statements; }
函数式接口
特征
- 可省略类型声明:不需要声明形式参数类型
- 可省略参数括号:一个参数无需定义括号,但多个参数需要定义括号
- 可省略花括号:如果主体只包含了一个语句就不需要使用花括号
- 可省略返回关键字:如果主体只包含了一个返回值语句则会自动返回
(1)强就强在lambda能替换匿名内部类 @FunctionalInterface注解,代表该接口为函数接口,是为lambda所服务的
Stream流
Optional类中map和flatMap的区别
如果是没有需要再进行细分的情况可以直接运用Map方法,里面的返回类型自己定义,非常具有灵活性
如果是需要进行再细分,运用flatMap方法能够很好的给你便利
Stream中的Peek操作
中间操作和终止操作
peek是中间操作
peek() 还有另一种用途:改变元素的内部状态
中间操作是流水线中的数据进行加工的, 它是一个懒操作, 并不会马上执行, 需要等待有终止操作的时候才会执行.
终止操作是Stream的启动操作, 当有终止操作的时候, Stream才会真正的开始执行.
因此, 这里可以解释上面的peek操作是一个中间操作, 所以没有任何输出.
peek()和map()的区别
如果想对流经的每个元素应用一个函数,从而改变某些状态,那么请用 forEach();
如果想打印流经的每个元素的状态(日志或 debug),这时应该用 peek();
peek()和forEach()的区别
使用peek操作流,流中的元素没有改变。
注意:peek对一个对象进行操作的时候,对象不变,但是可以改变对象里面的值
Stream.of("one", "two", "three", "four")
.filter(e -> e.length() > 3)
.peek(e -> System.out.println("Filtered value: " + e))
.map(String::toUpperCase)
.peek(e -> System.out.println("Mapped value: " + e))
.collect(Collectors.toList());
Stream中的reduce操作
关键概念:初始值的定义(Identity),累加器(Accumulator),组合器(Combiner)
累积操作之后返回
- Identity : 定义一个元素代表是归并操作的初始值,如果Stream 是空的,也是Stream 的默认结果
- Accumulator:定义一个带两个参数的函数,第一个参数是上个归并函数的返回值,第二个是Strem 中下一个元素。
- Combiner:调用一个函数来组合归并操作的结果,当归并是并行执行或者当累加器的函数和累加器的实现类型不匹配时才会调用此函数。
并行读流
如上文提到的,我们可以并行的使用 reduce() 方法。并行使用时,要注意一下几点:
- 结果和处理的顺序无关
- 操作不影响原有数据
- 操作没有状态和同样的输入有一样的输出结果
Consumer、Supplier、Predicate与Function 学习
Consumer(消费型)
Supplier(供给型)
Predicate(判断型
Function(转换型)
Consumer<String> consumer = t -> System.out.println(t);
List<String> list = Arrays.asList("hello", "I", "love", "you");
list.forEach(consumer);
Consumer总结:
- Consumer接口是一个消费型的接口,只要实现它的accept方法,就能作为消费者来输出信息。
- lambda、方法引用都可以是一个Consumer类型,因此他们可以作为forEach的参数,用来协助Stream输出信息。
- Consumer还有很多变种,例如IntConsumer、DoubleConsumer与LongConsumer等,归根结底,这些变种其实只是指定了Consumer中的泛型而已,方法上并无变化。
Supplier
Supplier是一个供给型的接口,我们可以无条件的从它这里获取东西。
Optional<Double> optional=Optional.empty();
Supplier<Double> supplier=()->new Random().nextDouble();
optional.orElseGet(supplier);
Supplier总结:
Supplier是一个供给型的接口,其中的get方法用于返回一个值。
Supplier也有很多的变种,例如IntSupplier、LongSupplier与BooleanSupplier等
Function
Function是一个功能型的接口,用于将一种类型的数据转化为另外一种类型的数据。