- 作者:老汪软件技巧
- 发表时间: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(Predicate super T> predicate);
Filtering unique elements
返回stream,过滤掉其中的重复元素。
截断Stream
通过java.util.stream.Stream#limit方法,截断Stream。
Skipping elements
丢弃前n个元素并返回stream。
map
Stream map(Function super 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(Predicate super T> predicate);
Returns whether all elements of this stream match the provided predicate
boolean allMatch(Predicate super T> predicate);
Returns whether no elements of this stream match the provided predicate
boolean noneMatch(Predicate super T> predicate);
reduce
T reduce(T identity, BinaryOperator<T> accumulator);
Numeric streams
IntStream, DoubleStream, LongStream,操作更加简单,但是装箱操作具有一定性能开销。
IntStream mapToInt(ToIntFunction super T> mapper);
LongStream mapToLong(ToLongFunction super T> mapper);
DoubleStream mapToDouble(ToDoubleFunction super 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