1、函数式接口
1.1 简介
函数式接口:只有一个抽象方法的接口。
函数式接口是 JDK8 新特性之一,在java.util.function
包下定义:
红圈出来的是四大函数式接口,其他的都是这四个函数式接口的组合。
1.2 Function
接口定义:
测试源码:
package pers.klb.myjuc;
import java.util.function.Function;
public class FunctionTest {
public static void main(String[] args) {
Function<String,String> function = (str)->{return str;};
System.out.println(function.apply("asd"));
}
}
运行结果:
1.3 Predicate
也称为断定型接口,源码定义:
测试代码:
package pers.klb.myjuc;
import java.util.function.Predicate;
public class FunctionTest {
public static void main(String[] args) {
Predicate<String> predicate = (str)->{return str.isEmpty(); };
System.out.println(predicate.test(""));
}
}
运行结果:
1.4 Consumer
也称为消费型接口,定义如下:
测试代码:
package pers.klb.myjuc;
import java.util.function.Consumer;
public class FunctionTest {
public static void main(String[] args) {
Consumer<String> consumer = (str)->{System.out.println(str);};
consumer.accept("sdadasd");
}
}
运行结果:
1.5 Supplier
也成为供给型接口,定义如下:
测试代码:
package pers.klb.myjuc;
import java.util.function.Supplier;
public class FunctionTest {
public static void main(String[] args) {
Supplier<Integer> supplier = ()->{ return 1024; };
System.out.println(supplier.get());
}
}
运行结果:
2、流式计算
2.1 什么是流
流(Stream) 到底是什么呢?
流指的是是数据渠道,用于操作数据源(集合、数组等)所生成的元素序列。“集合讲的是数据,流讲的是计算!”
Stream 自己不会存储元素。
Stream 不会改变源对象。相反,他们会返回一个持有结果的新 Stream。
Stream 操作是延迟执行的。这意味着他们会等到需要结果的时候才执行。
可以理解为流就是“计算流程”。
2.2 测试
假设现在给定若干个实体类的对象,再给出一些过滤条件,输出过滤后剩下的对象。
实体类代码如下:
class User {
private int id;
private String name;
private int age;
public User(int id, String name, int age) {
this.id = id;
this.name = name;
this.age = age;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
测试代码:
package pers.klb.myjuc;
import java.util.Arrays;
import java.util.List;
public class StreamTest {
public static void main(String[] args) {
User u1 = new User(1, "a", 21);
User u2 = new User(2, "b", 22);
User u3 = new User(3, "c", 23);
User u4 = new User(4, "d", 24);
User u5 = new User(6, "e", 25);
// 集合就是存储
List<User> list = Arrays.asList(u1, u2, u3, u4, u5);
}
}
过滤条件为:
1、ID 必须是偶数;
2、年龄必须大于23岁;
3、用户名转为大写字母;
4、用户名字母倒着排序;
5、只输出一个用户。
那么,如何用一行代码实现这五个过滤呢?
答案是使用 Stream,它在java.util.stream
包下,看一下它的 API :
首先,Collection
提供了一个方法stream()
用来获取集合的 Stream 对象。结合 API ,我们可以使用以下代码实现一行过滤:
public class StreamTest {
public static void main(String[] args) {
User u1 = new User(1, "a", 21);
User u2 = new User(2, "b", 22);
User u3 = new User(3, "c", 23);
User u4 = new User(4, "d", 24);
User u5 = new User(6, "e", 25);
// 集合就是存储
List<User> list = Arrays.asList(u1, u2, u3, u4, u5);
// 计算交给Stream流
// lambda表达式、链式编程、函数式接口、Stream流式计算
list.stream()
.filter(u->{return u.getId()%2==0;})
.filter(u->{return u.getAge()>23;})
.map(u->{return u.getName().toUpperCase();})
.sorted((uu1,uu2)->{return uu2.compareTo(uu1);})
.limit(1)
.forEach(System.out::println);
}
}
这是一个链式编程,每一个方法调用完又得到一个 Stream 对象,方法的参数皆为函数式接口,可以使用 lambda 表达式来写。