一、说明
1.函数式接口的使用说明说明:
- 函数式接口是Java8的一个新特性。
- 如果一个接口中,只声明了一个抽象方法,则此接口就称为函数式接口。
- 我们可以在一个接口上使用 @FunctionalInterface 注解,这样做可以检查它是否是一个函数式接口。
- Lambda表达式的本质:作为函数式接口的实例。
2.Java8中关于Lambda表达式提供的4个基本的函数式接口:
3.何时使用给定的函数式接口?
如果我们开发中需要定义一个函数式接口,首先看看在已有的jdk提供的函数式接口是否提供了能满足需求的函数式接口。如果有,则直接调用即可,不需要自己再自定义了。
二、详细说明
1.消费型接口:
Consumer接口代表了在一个输入参数上需要进行的操作。
@FunctionalInterface
public interface Consumer<T> {
void accept(T t);
default Consumer<T> andThen(Consumer<? super T> after) {
Objects.requireNonNull(after);
return (T t) -> { accept(t); after.accept(t); };
}
}
举例说明:
函数式接口相当于把一个行为当作参数传入一个方法中,在这个例子中,System.out.println(item)是Consumer 的行为,也就是打印出所传入的参数str。
public class ConsumerTest {
public static void main(String[] args) {
ConsumerTest test = new ConsumerTest();
//传入字符串,然后打印
// test.print("hello java!", (item) -> System.out.println(item));
test.print("hello java!", System.out::println);//lambda写法
}
//接受str字符串参数并进行消费
public void print(String str, Consumer<String> consumer) {
consumer.accept(str);
}
}
举例二:
使用匿名实现类指定消费的行为,并传入数据进行消费。
Consumer<Integer> consumer = num -> {
int a = num + 2;
System.out.println(a);// 12
};
consumer.accept(10);
2.供给型接口
Supplier供给型接口提供一个给定参数类型的结果
@FunctionalInterface
public interface Supplier<T> {
T get();
}
举例一:产生一些整数,并放入集合中
import java.util.function.Supplier;
public class SupplierTest {
public static void main(String[] args) {
SupplierTest test = new SupplierTest();
test.getNumList(10,()->(int)(Math.random()*100));
//产生一些整数,并放入集合中. int num 为产生的个数
public List<Integer> getNumList(int num, Supplier<Integer> supplier) {
List<Integer> list = new ArrayList<>();
for(int i = 0;i<num;i++) {
Integer n =supplier.get();
list.add(n);
}
return list;
}
举例二:使用CompletableFuture.supplyAsync方法异步多线程处理业务逻辑
public class SupplierTest {
public static void main(String[] args) throws ExecutionException, InterruptedException {
// 供给型接口Supplier
//public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier)
CompletableFuture<Integer> num1 = CompletableFuture.supplyAsync(() -> 1);
CompletableFuture<Integer> num2 = CompletableFuture.supplyAsync(() -> 2);
CompletableFuture<Integer> num3 = CompletableFuture.supplyAsync(() -> 3);
CompletableFuture<Integer> num4 = CompletableFuture.supplyAsync(() -> 4);
//3 join等待所有线程全部执行完成
CompletableFuture
.allOf(num1,
num2,
num3,
num4)
.join();
System.out.println(num1.get());//1
System.out.println(num2.get());//2
System.out.println(num3.get());//3
System.out.println(num4.get());//4
}
}
3.函数型接口
Function接口接收一个参数,并返回单一的结果
@FunctionalInterface
public interface Function<T, R> {
//核心方法
R apply(T t);
default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
Objects.requireNonNull(before);
return (V v) -> apply(before.apply(v));
}
default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {
Objects.requireNonNull(after);
return (T t) -> after.apply(apply(t));
}
static <T> Function<T, T> identity() {
return t -> t;
}
}
举例一:处理字符串数据
class FunctionTest{
public static void main(String[] args){
String newStr = strHandler("我是函数型接口",(str)->str.subString(2,5));
System.out.println(newStr);
}
public String strHandler(String str, Function<String,String> fun){
return fun.apply(str);
}
4.段言型接口
Predicate接口是一个布尔类型的函数,该函数只有一个输入参数
public interface Predicate<T> {
//核心方法
boolean test(T t);
default Predicate<T> and(Predicate<? super T> other) {
Objects.requireNonNull(other);
return (t) -> test(t) && other.test(t);
}
default Predicate<T> negate() {
return (t) -> !test(t);
}
default Predicate<T> or(Predicate<? super T> other) {
Objects.requireNonNull(other);
return (t) -> test(t) || other.test(t);
}
static <T> Predicate<T> isEqual(Object targetRef) {
return (null == targetRef)
? Objects::isNull
: object -> targetRef.equals(object);
}
}
举例一:筛选出长度大于4的字符串,并放入新的集合中
class PredicateTest{
public static void main(String[] args){
List<String> list =Arrays.asList("Hello","World","Function","Lambda","Java");
filterStr(list,(s) -> s.length()>4);
System.out.println(newList);
}
public List<String> filterStr(List<String> list,Predicate<String> pre){
List<String> newList = new ArrayList<>();
for(String str : list){
if(pre.test(str)){
newList.add(str);
}
}
return newList;
}