函数式接口

Jdk8 新增一个重要的包:java.util.function。该包下所有的接口都是函数式接口:@FunctionalInterface

主要分为四大类:SupplierConsumerPredicateFunction

接口 方法 参数 返回值 说明
Supplier T get(); T 供给型;无参,返回一个指定泛型的对象
Consumer void accept(T t); T 消费型;传入一个指定泛型的参数,无返回值
Predicate boolean test(T t); T Boolean 断言型:输入一个参数,返回判断结果
Function<T, R> R apply(T t); T R 方法型;输入一个参数,得到一个结果

如果T/Rint/long/double,该包下定义了相关接口,如IntSupplierIntConsumerIntFunctionIntPredicate……

针对参数扩展延伸:

接口 方法/继承关系 说明
BiConsumer<T, U> void accept(T t, U u); 接收T对象和U对象,不返回值
BiPredicate<T, U> boolean test(T t, U u); 接收T对象和U对象,返回Boolean
BiFunction<T, U, R> R apply(T t, U u); 接收T对象和U对象,返回R对象
BinaryOperator extends BiFunction<T,T,T>;
即 T apply(T t, T u);
接收两个T对象,返回T对象
UnaryOperator extends Function<T, T>
即 T apply(T t);
接收T对象,返回T对象

一、Supplier

1、源码

1
2
3
4
@FunctionalInterface
public interface Supplier<T> {
T get();
}

2、使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
 public void supplierExample() {
/*1、使用Supplier接口实现方法*/
Supplier<Integer> supplier = new Supplier<Integer>() {
@Override
public Integer get() {
return new Random().nextInt();
}
};
/*2、使用lambda简写*/
Supplier<Integer> supplier1 = () -> new Random().nextInt();
Supplier<Double> supplier2 = Math::random;
System.out.println(supplier1.get());
System.out.println(supplier2.get());
}

3、在JDK8 中常见用处

如: Optional 对象的 orElseGetorElseThrow 方法

1
2
3
User user = null; // 
user = Optional.ofNullable(user).orElseGet(User::new);
user = Optional.ofNullable(user).orElseThrow(() -> new IllegalArgumentException("user is null"));

二、Consumer

1、源码

1
2
3
4
@FunctionalInterface
public interface Consumer<T> {
void accept(T t);
}

2、使用

1
2
3
4
5
6
7
8
9
10
11
12
13
public void consumerExample() {
/*1、使用Consumer接口实现方法*/
Consumer<String> consumer = new Consumer<String>() {
@Override
public void accept(String s) {
System.out.println(s.toLowerCase());
}
};
/*2、使用lambda简写*/
Consumer<String> consumer1 = (s) -> {
System.out.println(s.toLowerCase());
};
}

3、在JDK8 中常见用处

如 Iterator 的forEach方法,Stream 的forEach方法:

1
2
3
4
5
List<User> userList = new ArrayList<>(); //
userList.forEach((i) -> i.setIdCardNo(""));

Stream<String> stringStream = Stream.of("a", "b", "c");
stringStream.forEach(System.out::println); // stringStream.forEach(i-> System.out.println(i));

三、Predicate

1、源码

1
2
3
4
@FunctionalInterface
public interface Predicate<T> {
boolean test(T t);
}

2、使用

1
2
3
4
5
6
7
8
9
10
11
12
public static void predicateExample() {
/*1、使用Predicate接口实现方法*/
Predicate<Integer> predicate = new Predicate<Integer>() {
@Override
public boolean test(Integer integer) {
return integer < 100;
}
};
/*2、使用lambda简写*/
Predicate<Integer> predicate1 = (i -> i < 1000);
System.out.println(predicate1.test(100));
}

3、在JDK8 中常见用处

如:如 Stream 的 filter 方法需要的参数就是 Predicate 接口

1
2
3
4
5
6
IntStream.of(1, 2, 3, 4, 5, 6)
.filter(i -> i % 2 == 0) // 符合条件的偶数构成新的 Stream
.forEach(System.out::println);

String key = "";
Optional.of(key).filter(i -> !StringUtils.isEmpty(i)).orElseThrow(() -> new IllegalArgumentException("key is empty"));

四、Function<T, R>

1、源码

1
2
3
4
@FunctionalInterface
public interface Function<T, R> {
R apply(T t);
}

2、使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public static void functionExample() {
/*1、使用 Function 接口实现方法*/
Function<String, Integer> function = new Function<String, Integer>() {
@Override
public Integer apply(String s) {
return s.length();
}
};
/*2、使用lambda简写*/
Function<String, Integer> function1 = String::length;// Function<String,Integer> function1=(s)->s.length();
System.out.println(function1.apply("abcd"));
Function<User, String> function2 = (user) -> {
return user.getMobile().replaceAll("(\\d{4})\\d{10}(\\w{4})", "$1******$2");
};
// Function<User, String> function2 = (user) -> user.getMobile().replaceAll("(\\d{4})\\d{10}(\\w{4})", "$1******$2");
User user = new User();
user.setMobile("500239199709272921");
System.out.println(function2.apply(user));
}

3、在JDK8 中常见用处

如 HashMap的 computeIfAbsent

1
2
3
4
Map<Integer, User> map = new HashMap<>();
int id = 1;
user = map.computeIfAbsent(id, i -> new User(id));
// java8 之前写法: if (map.get(id) == null) { map.put(id, new User(id)); }

如 Stream 的 map 转换流

1
2
3
4
5
6
List<User> userList=new ArrayList<>();
userList.add(new User(1,"张三","xxx","xxx"));
userList.add(new User(2,"李四","xxx","xxx"));
userList.add(new User(3,"王五","xxx","xxx"));
List<String> names = userList.stream().map(User::getName).collect(Collectors.toList());
System.out.println(names);