• 作者:老汪软件技巧
  • 发表时间:2024-10-08 17:00
  • 浏览量:

Lambda表达式

Lambda表达式可以被理解为可以传递的匿名函数的简洁表示:它没有名称,但它有一个参数列表、一个主体、一个返回类型,可能还有一个可以抛出的异常列表。

可以在函数式接口的上下文中使用lambda表达式。函数式接口是只有一个抽象方法的接口。只要它只指定了一个抽象方法,如果接口有许多默认方法,它仍然是一个函数式接口。

@FunctionalInterface  
public interface Runnable {  
    /**  
    * Runs this operation.  
    */  
    void run();  
}

函数描述符

函数接口抽象方法的签名基本上描述了lambda表达式的签名。我们称这个抽象方法为函数描述符。

关于 @FunctionalInterface此注释用于表示该接口旨在成为函数式接口。如果使用@FunctionalInterface注释定义接口,并且它不是功能接口,编译器将返回一个有意义的错误。例如,错误消息可能是“Multiple non-overriding abstract methods found in interface”,以表明有多个抽象方法可用。@FunctionalInterface注释不是强制性的,但当接口为此目的而设计时,使用它是一个很好的做法。

类型检查、类型推断和限制

Lambda的类型是从使用lambda的上下文中推断出来的。上下文中lambda表达式的预期类型(例如,传递给的方法参数或分配给的方法变量)称为目标类型。

Lambda使用局部变量

Lambda可以不受限制地捕获(即在其主体中引用)实例变量和静态变量。但局部变量必须明确为final或者实际是final(只赋值一次)。局部变量的作用域仅限于当前方法或块,这意味着它们不会被多个线程同时访问。如果允许lambda表达式修改局部变量,可能会导致线程安全问题。通过限制lambda表达式只能访问final或有效最终变量,Java确保了这些变量在lambda表达式中是不可变的。这有助于避免并发访问时的数据竞争和不一致问题。

方法引用

方法引用可以被视为只调用特定方法的lambdas的简写。

Stream

定义:stream是来自支持数据处理操作的源的元素序列。stream通过声明式的风格处理数据,我们可以通过Stream提供的API实现一系列数据操作而不是重复实现这些方法。

Stream vs Collection

collection中的元素是计算完成以后放入其中的,相比之下,流是一个概念上固定的数据结构(不能从中添加或删除元素),其元素是按需计算的。Stream中的数据只能被消费一次,与iterator类似:

collection使用显示迭代的方式遍历集合,但是Stream使用隐式的方式,这意味着遍历的顺序是不确定的,被优化过的,比如可以使用并行化处理。

Operationsintermediate operation

如过滤或排序,返回另一个stream作为返回类型,这允许操作连接以形成查询。重要的是,在流管道上调用终端操作之前,中间操作不会执行任何处理——它们是懒惰的。这是因为中间操作通常可以通过终端操作合并并处理为单通道。

terminal operations

产生非stream结果,比如List,Integer。

Working with streams

综上所述,处理流通常涉及三个项目:Java 8 in Action: Lambdas, Streams, and functional-style programming

Filtering and slicing

Stream<T> filter(Predicatesuper T> predicate);

Filtering unique elements

返回stream,过滤掉其中的重复元素。

截断Stream

通过java.util.stream.Stream#limit方法,截断Stream。

Skipping elements

Lambda,StreamandFunction_Lambda,StreamandFunction_

丢弃前n个元素并返回stream。

map

 Stream map(Functionsuper T, ? extends R> mapper);

将mapper方法应用在每个stream的元素上,返回一个新类型的Stream。

FlatMap

它用于将一个流中的每个元素转换为另一个流,然后将这些流扁平化为一个单一的流。flatMap 在处理嵌套的集合或需要将多个流合并为一个流时特别有用。

anyMatch, allMatch and noneMatch

Returns whether any elements of this stream match the provided predicate.

boolean anyMatch(Predicatesuper T> predicate);

Returns whether all elements of this stream match the provided predicate

boolean allMatch(Predicatesuper T> predicate);

Returns whether no elements of this stream match the provided predicate

boolean noneMatch(Predicatesuper T> predicate);

reduce

T reduce(T identity, BinaryOperator<T> accumulator);

Numeric streams

IntStream, DoubleStream, LongStream,操作更加简单,但是装箱操作具有一定性能开销。

IntStream mapToInt(ToIntFunctionsuper T> mapper);
LongStream mapToLong(ToLongFunctionsuper T> mapper);
DoubleStream mapToDouble(ToDoubleFunctionsuper T> mapper);

使用boxed转换为包装类的Stream。

构建Stream

Collecting data with streams

Collector接口方法的实现定义了如何在流上执行reduce操作。

计算stream元素个数

java.util.stream.Collectors#counting

最大值与最小值

java.util.stream.Collectors#maxBy,

java.util.stream.Collectors#minBy

同时获取最大值、最小值、平均值、sum及count

joining

调用每个Stream每个元素的toString方法,连接成单一字符串。

grouping

将stream中的元素进行分类,java.util.stream.Collectors#groupingBy(java.util.function.Function