Jave8的一些新特性
- 函数式编程
- Lambda表达式
- 流(stream)
- 接口(interface)默认方法
我们用一个例子来了解一下这些新特性:
场景:从人群中分别找出大于30岁的与体重小于75KG的人
- 我们定义如下People类
public class People {
private int age;
private int weight;
public People(int age, int weight) {
this.age = age;
this.weight = weight;
}
// Get Set方法略
}
- 获取人群方法
private static List<People> createPeopleList() {
List<People> peopleList = new ArrayList<People>();
for (int i = 0; i < 100; i++) {
peopleList.add(new People(i, i * 2));
}
return peopleList;
}
- Java7及以前的实现
List<People> peopleList = createPeopleList();
List<People> peopleAge30 = new ArrayList<>();
for (People people : peopleList) {
if (people.getAge() > 30) {
peopleAge30.add(people);
}
}
List<People> peopleWeigth75 = new ArrayList<>();
for (People people : peopleList) {
if (people.getWeight() < 75) {
peopleWeigth75.add(people);
}
}
- 优化
- 我们定义一个接口与一个过滤方法
// 接口
interface Test<T> {
boolean test(T t);
}
// 过滤方法
private static List<People> filter(List<People> peopleList, Test<People> test) {
List<People> newPeopleList = new ArrayList<>();
for (People people : peopleList) {
if (test.test(people)) {
newPeopleList.add(people);
}
}
return newPeopleList;
}
- 优化实现方法
List<People> filter1 = filter(peopleList, new Test<People>() {
@Override
public boolean test(People people) {
return people.getAge() > 30;
}
});
List<People> filter1 = filter(peopleList, new Test<People>() {
@Override
public boolean test(People people) {
return people.getWeight() > 30;
}
});
使用Java8新特性优化
- 函数式编程
- 我们在People中定义一个方法来判断当前实例是否大于30岁
public boolean age30() {
return age > 30;
}
- 那在上面优化实现的方法基础上Java8可以这样写
Test<People> test = People::age30;
List<People> filter2 = filter(peopleList, test);
// 与Java7中匿名内部类相比我们直接将age30()方法传递给了过滤方法
这种把函数做为值传递给方法的编程风格我们叫做函数式编程
- 若我们不愿意写age30()方法我们也可以采用以下方式实现
test = (People people) -> people.getAge() > 30;
List<People> filter3 = filter(peopleList, test);
// 与上面People::age30相比这种写法可看做是写了一个匿名函数
这种可传递的匿名函数写法我们叫做Lambda表达式
- 若我们不愿意写filter()方法我们可以采用以下方式实现
List<People> filter4 = peopleList.stream()
.filter(People::age30)
.collect(Collectors.toList());
List<People> filter5 = peopleList.stream()
.filter((People people) -> people.getAge() > 30)
.collect(Collectors.toList());
这就是流(Stream)写法,这种写法更直观,更简洁,其内部实现了并行化的处理,在并行编程中无需我们自己处理多线程带来的问题。Stream Api 在处理大数据时更有优势,一方面是因为在处理大数据时,流Api能够轻易实现并行处理,速度更快;另一方面,流api无需像集合api一样,一次性将数据全部加载进内存后才能处理。
- 查看源码会发现ArrayList与其父类均没有实现stream()方法,查看Collection接口stream()方法
default Stream<E> stream() {
return StreamSupport.stream(spliterator(), false);
}
这便是接口(interface)默认方法,默认方法是接口为定义在接口中的方法提供的默认实现,使用default关键词声明,有了默认方法,接口就可以包含实现类没有提供实现的方法签名。