本文翻译自《Java 8 Explained: Applying Lambdas to Java Collections》。
Lambdas表达式是Java 8的主题,在Java平台上我们期待了很久。但是,如果如果我们不在集合中使用它的话,就损失了很大价值。把现有接口迁移成为lambda风格接口的问题已经通过default methods,也就是defender methods解决了。在这篇文章里面我们来看一看Java集合里面的批量数据操作(bulk operation)。
批量操作
最初的变更文档已经说了,批量操作是“给Java集合框架添加的用以批量操作数据的功能,而它是基于lambda函数实现的”。引用的话也就是在说,lambda移植到Java 8对我来说的实际目的,就是它提供了一种新的使用集合的方式,这也是最重要的特性,表达式操作符可以并行执行,并且lambda是一个比常规表达式操作符更好的工具。
内部和外部的迭代
历史上,Java集合是不能够表达内部迭代的,而只提供了一种外部迭代的方式,也就是for或者while循环。要描述内部迭代,我们需要用到LambdaJ这样的类库:
1
2
|
List persons = asList( new Person( "Joe" ), new Person( "Jim" ), new Person( "John" ));
forEach(persons).setLastName( "Doe" );
|
从上面的例子可以看出,我们不需要关心last name是怎么被设置到每一个person对象里面去的,也许这样的行为是支持并发执行的。现在我们可以在Java 8中使用类似的表达了:
1
|
persons.forEach(p -> p.setLastName( "Doe" ))
|
内部迭代其实和集合的批量操作并没有密切的联系,这只是一个小小的特性,借助它我们感受到语法表达上的变化。真正有意思的和批量操作相关的是新的流(stream)API。
流API
新的java.util.stream包已经添加进JDK了,现在我们可以借助Java 8执行filter/map/reduce风格的操作了。
流API允许我们声明对数据进行串行或者并行的操作:
1
2
3
|
List persons = … // sequential version
Stream stream = persons.stream(); //parallel version
Stream parallelStream = persons.parallelStream(); |
java.util.stream.Stream接口提供了批量数据操作的入口,取得了对流实例的引用,我们就可以对集合执行如下有趣的任务了:
Filter
在数据流中实现过滤功能是首先我们可以想到的最自然的操作了。Stream接口暴露了一个filter方法,它可以接受表示操作的Predicate实现来使用定义了过滤条件的lambda表达式。
1
2
|
List persons = … Stream personsOver18 = persons.stream().filter(p -> p.getAge() > 18 );
|
Map
假使我们现在过滤了一些数据,比如转换对象的时候。Map操作允许我们执行一个Function的实现(Function<T,R>的泛型T,R分别表示执行输入和执行结果),它接受入参并返回。首先,让我们来看看怎样以匿名内部类的方式来描述它:
1
2
3
4
5
6
7
8
|
Stream students = persons.stream() .filter(p -> p.getAge() > 18 )
.map( new Function() {
@Override
public Student apply(Person person) {
return new Student(person);
}
});
|
现在,把上述例子转换成使用lambda表达式的写法:
1
2
3
|
Stream map = persons.stream() .filter(p -> p.getAge() > 18 )
.map(person -> new Student(person));
|
Lambda在把参数传给map方法的时候,实际却并没有使用这个参数,那么我们就可以写成这样:
1
2
3
|
Stream map = persons.stream() .filter(p -> p.getAge() > 18 )
.map(Student:: new );
|
Collect
“流”抽象天生就该是持续的,我们使用流来描述操作,但是如果我们要获取最终结果的话,必须收集流产生的最终结果。Stream API提供了一系列“最终”的方法,collect()方法就是其中的一个,我们借此可以收集操作的最终结果:
1
2
3
4
|
List students = persons.stream() .filter(p -> p.getAge() > 18 )
.map(Student:: new )
.collect( new Collector>() { … });
|
幸运的是,大多数情况下你不需要自己实现Collector接口,而是利用Collectors工具类:
1
2
3
4
|
List students = persons.stream() .filter(p -> p.getAge() > 18 )
.map(Student:: new )
.collect(Collectors.toList());
|
或者,如果我们想使用特定的实现类来收集结果:
1
2
3
4
|
List students = persons.stream() .filter(p -> p.getAge() > 18 )
.map(Student:: new )
.collect(Collectors.toCollection(ArrayList:: new ));
|
并行和串行
一个使用新的Stream API有趣的特性是它从来都不需要所谓串行或者并行的方法,可以从一开始就并行地消费数据,或者在处理流中的任意时刻转为串行的。
1
2
3
4
5
6
|
List students = persons.stream() .parallel()
.filter(p -> p.getAge() > 18 ) // filtering will be performed concurrently
.sequential()
.map(Student:: new )
.collect(Collectors.toCollection(ArrayList:: new ));
|
这里有隐藏的一点是,数据处理的并行部分会自动地自我管理,不需要我们自己来处理并发的问题。
总结
好了,要结束了。新的Stream API和lambda表达式给Java 8带来了很多新的特性。当然,在这篇文章以外还有很多没有谈及到,但愿很快我可以给你带给你更多有趣的特性。
文章系本人原创,转载请保持完整性并注明出自《四火的唠叨》
相关推荐
在这个"Java8集合 CompletableFuture lambda表达式 新的TimeAPI 和ForkJoin Demo包"中,我们可以深入探讨以下几个关键知识点: 1. **Lambda表达式**: Lambda表达式是Java 8的一大亮点,它简化了对匿名函数的处理...
Java 8 中的 Lambda 表达式是语言的重大更新,它引入了函数式编程的概念,使得代码更加简洁、易读。Lambda 表达式的主要目的是简化处理匿名内部类的情况,尤其是当这些类只需要一个方法时。 在传统的 Java 编程中,...
Java8的Lambda表达式是Java语言的一次重大更新,它引入了函数式编程的概念,极大地简化了处理匿名函数的方式,特别是在处理集合和并发操作时。Lambda表达式使得代码更加简洁、易读,同时也提升了程序的执行效率。在...
在Java 8中,Lambda 表达式与功能接口紧密相连。功能接口是指只有一个抽象方法的接口。例如,`java.util.function.Function,R>` 接口表示一个接收类型 T 参数并返回类型 R 结果的函数。Lambda 表达式可以作为这些...
在这个“java8lambda表达式Demo”中,我们将探讨Lambda表达式在Android Studio工程中的实际应用。 Lambda表达式的核心概念是匿名函数,即没有名字的函数。在Java 8之前,如果需要定义一个简单的功能,如比较两个...
Java 8中的Lambda表达式为集合的处理提供了非常便利的工具,如Predicate接口可以用于筛选集合。例如,从一个包含名字的列表中筛选出长度大于或等于4的字符串可以写为: ```java List<String> names = Arrays.asList...
Lambda表达式是Java 8中的一种语法糖,它允许开发者以更简洁的方式定义无状态、无副作用的函数。在描述中提到的代码示例中,对比了使用匿名类和Lambda表达式实现相同功能的方法。 首先,让我们看看匿名类的使用。在...
Lambda表达式在Java中被设计为一种匿名函数,可以没有名称地传递,并且可以当作参数或返回值。这种特性在处理高阶函数时特别有用,例如在集合API的流(Stream API)操作中。 **语言篇:** 1. **定义与语法**: Java...
Java 8 中引入了几个重要的流(Stream)API,与 Lambda 表达式配合使用,可以实现高效且易于理解的集合操作。例如,我们可以使用 `Arrays.stream()` 将数组转换为流,然后通过 `filter()`, `map()`, `reduce()` 等方法...
Java Lambda表达式是Java 8引入的一个重要特性,它极大地简化了函数式编程风格的实现。Lambda表达式允许我们将函数作为一个值传递,就像传递其他数据类型一样。这在处理集合、事件驱动编程以及多线程等场景下尤其...
Lambda表达式是Java编程语言中的一个关键特性,自Java 8开始引入,它极大地简化了函数式编程,尤其是在处理集合数据时。Lambda表达式的主要目的是为了创建匿名函数,即没有名字的函数,它可以被当作一个值传递给方法...
【Java8】Lambda表达式 和 Stream API 是Java编程语言中的两个重要创新,它们极大地提升了代码的简洁性和可读性,特别是在处理集合数据时。这里我们将深入探讨这两个特性,并结合实际示例来理解它们的工作原理。 ...
此外,文中还包括了大量的代码示例,演示了Lambda表达式在集合操作和流API中的实际应用。最后,文章讨论了一些常见问题及其解决办法,如性能考虑、变量修改错误等。 适合人群:已经熟悉Java基础,希望深入学习和理解...
示例中通过Lists.newArrayList()创建了学生对象的列表,并使用Lambda表达式进行了一系列操作,展示了如何结合使用Java集合类和Lambda表达式对集合数据进行操作。这种方式使代码更加简洁,易于理解和维护。 8. 测试...
总的来说,Java 8的Lambda表达式为开发者提供了更优雅、更简洁的方式来处理集合数据,简化了代码,并引入了函数式编程的思维方式。通过熟练掌握Lambda表达式,你可以编写出更高效、更易于理解和维护的Java代码。
在 Java 8 中,Lambda 表达式和 Stream API 的结合是处理集合数据的强大工具。借助 Stream API 提供的一系列方法,如 filter()、map()、sorted()、collect() 等,可以非常方便地对集合数据进行各种复杂的操作。此外...
Lambda 表达式的语法糖是指 Java 8 中引入的 Lambda 表达式语法,允许开发者使用更简洁的方式编写 Lambda 表达式。Lambda 语法糖包括参数列表、箭头和函数体三个部分。 1.1.1 语法 Lambda 表达式的语法糖可以使用...
本文主要介绍了Java8 中使用Lambda表达式给List集合排序的实现,通过示例代码详细地介绍了整个排序过程,涵盖了顺序排序、逆序排序和多条件排序等多种情况。 Lambda表达式与函数式编程 在Java8 中,Lambda表达式是...