在java8中,满足下面任意一个条件的接口都是函数式接口
- 被@FunctionalInterface注释的接口,满足@FunctionalInterface注释的约束。
- 没有被@FunctionalInterface注释的接口,但是满足@FunctionalInterface注释的约束
@FunctionalInterface注释的约束
- 接口有且只能有个一个抽象方法,只有方法定义,没有方法体
- 在接口中覆写Object类中的public方法,不算是函数式接口的方法。
- 该注解不是必须的,如果一个接口符合"函数式接口"定义,那么加不加该注解都没有影响。加上该注解能够更好地让编译器进行检查。 如果编写的不是函数式接口,但是加上了@FunctionInterface,那么编译器会报错
@FunctionalInterface简单示例
public static void main(String[] args) {
System.out.println(addstr("a", a -> a + "b"));
System.out.println(method("a", "b", (a, b) -> a + b));
System.out.println(method("梁胖子", "你", (a, b) -> a + "❤" + b));
// JDK8中有双冒号的用法,就是把方法当做参数传过去
Test1 amethod = My::getInstance;
System.out.println(method("a", "b", amethod));
}
@FunctionalInterface
public interface Test2 {
String invoke(String profile);
}
@FunctionalInterface
public interface Test1 {
String invoke(String profile, String document);
}
public static String method(String profile, String document, Test1 a) {
return a.invoke(profile, document);
}
public static String getInstance(String profile, String document) {
return profile + document;
}
public static String addstr(String str, Test2 test2) {
return test2.invoke(str);
}
接口名 | 说明 |
Function<T,R> | 接收一个T类型的参数,返回一个R类型的结果 |
Consumer<T> | 接收一个T类型的参数,不返回值 |
Predicate<T> | 接收一个T类型的参数,返回一个boolean类型的结果 |
Supplier<T> | 不接受参数,返回一个T类型的结果 |
BiFunction<T, U, R> | 接收T类型和U类型的两个参数,返回一个R类型的结果 |
BiConsumer<T , U> | 接收T类型和U类型的两个参数,不返回值 |
BiPredicate<T, U> | 接收T类型和U类型的两个参数,返回一个boolean类型的结果 |
许多jdk8的方法使用此类接口,其实都是Lamada表达式,下面看下此类接口的实际应用详细代码
public static void main(String[] args) {
// Function<T,R> 接收一个T类型的参数,返回一个R类型的结果
Function<String, String> function = item -> item + item;
// Consumer<T>接收一个T类型的参数,不返回值
Consumer<String> consumer = iterm -> {
System.out.println(iterm);
};
// Predicate<T>接收一个T类型的参数,返回一个boolean类型的结果
Predicate<String> predicate = iterm -> "33".equals(iterm);
// Supplier<T>不接受参数,返回一个T类型的结果
Supplier<String> supplier = () -> new String("");
List<String> list = Arrays.asList("1", "2", "3", "5", "6");
list.stream().map(function).filter(predicate).forEach(consumer);
BiFunction<String, String, String> biFunction = (str1, str2) -> str1 + str2;
BiConsumer<String, String> biConsumer = (str1, str2) -> System.out.println(str1 + str2);
BiPredicate<String, String> biPredicate = (str1, str2) -> str1.length() > str2.length();
Map<String, String> map = new HashMap<>();
map.put("java", "boot");
map.put("spring", "boot");
map.forEach(biConsumer);
System.out.println(biFunction.apply("qunimade ", "zhendifan "));
}
使用default关键字创在interface中直接创建一个default方法,该方法包含了具体的实现代码,说白了就是接口中可以有实现
@FunctionalInterface
public interface BiFunction<T, U, R> {
/**
* Applies this function to the given arguments.
*
* @param t the first function argument
* @param u the second function argument
* @return the function result
*/
R apply(T t, U u);
/**
* Returns a composed function that first applies this function to
* its input, and then applies the {@code after} function to the result.
* If evaluation of either function throws an exception, it is relayed to
* the caller of the composed function.
*
* @param <V> the type of output of the {@code after} function, and of the
* composed function
* @param after the function to apply after this function is applied
* @return a composed function that first applies this function and then
* applies the {@code after} function
* @throws NullPointerException if after is null
*/
default <V> BiFunction<T, U, V> andThen(Function<? super R, ? extends V> after) {
Objects.requireNonNull(after);
return (T t, U u) -> after.apply(apply(t, u));
}
}
嵌套执行函数andThen 执行BiFunction函数参数结果当做Function的参数执行
public static void main(String[] args) {
Function<String, String> first = a -> {
return a + "第二次";
};
BiFunction<String, String, String> second = (str1, str2) -> {
return str1 + str2;
};
String apply = second.andThen(first).apply("第一次", "~");
System.out.println(apply);
}
输出结果:第一次~第二次