函数式接口
Lambda基本语法:() ->
函数式接口
- 如果一个接口只有一个抽象方法,那么该接口就是一个函数式接口。
- 如果我们在某个接口上声明了
@FunctionalInterface
注解,那么编译器就会按照函数式接口的定义来要求该接口 - 如果某个接口只有一个抽象方法,但我们并没有给该接口声明
@FunctionalInterface
注解,那么编译器依旧会将该接口看作是函数式接口。
@FunctionalInterface
注解
通过阅读代码注释我们得知:
- functional interface只能有一个抽象方法
- 如果接口重写了
java.lang.Object
中的方法,比如toString()
,并不会增加接口的抽象方法数量
/**
* An informative annotation type used to indicate that an interface
* type declaration is intended to be a <i>functional interface</i> as
* defined by the Java Language Specification.
*
* Conceptually, a functional interface has exactly one abstract
* method. Since {@linkplain java.lang.reflect.Method#isDefault()
* default methods} have an implementation, they are not abstract. If
* an interface declares an abstract method overriding one of the
* public methods of {@code java.lang.Object}, that also does
* <em>not</em> count toward the interface's abstract method count
* since any implementation of the interface will have an
* implementation from {@code java.lang.Object} or elsewhere.
*
* <p>Note that instances of functional interfaces can be created with
* lambda expressions, method references, or constructor references.
*
* <p>If a type is annotated with this annotation type, compilers are
* required to generate an error message unless:
*
* <ul>
* <li> The type is an interface type and not an annotation type, enum, or class.
* <li> The annotated type satisfies the requirements of a functional interface.
* </ul>
*
* <p>However, the compiler will treat any interface meeting the
* definition of a functional interface as a functional interface
* regardless of whether or not a {@code FunctionalInterface}
* annotation is present on the interface declaration.
*
* @jls 4.3.2. The Class Object
* @jls 9.8 Functional Interfaces
* @jls 9.4.3 Interface Method Body
* @since 1.8
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface FunctionalInterface {}
针对第一点很好理解,接口只能有一个抽象方法,我们重点看下第二点
这样也是符合函数式接口要求的,因为toString()
是Object中的方法,是所有对象的父类
@FunctionalInterface
public interface MyInterface {
void test();
@Override
String toString();
}
public static void main(String[] args) {
MyInterface myInterface = () -> {
System.out.println("myInterface");
};
System.out.println("我的类型是:"+ myInterface.getClass());
System.out.println("我的父类是:"+ myInterface.getClass().getSuperclass());
System.out.println("我的父类是:"+ myInterface.getClass().getSuperclass());
System.out.println("我的抽象方法数量是:"+ myInterface.getClass().getInterfaces().length);
System.out.println("我的抽象方法是:"+ myInterface.getClass().getInterfaces()[0]);
}
输出信息:
我的类型是:class a.Test$$Lambda$1/990368553
我的父类是:class java.lang.Object
我的父类是:class java.lang.Object
我的抽象方法数量是:1
我的抽象方法是:interface a.MyInterface
Jdk8提供的函数式接口
Consumer
消费一个数据
代表了接受一个输入参数并且无返回的操作
Consumer.accept(T t) 接收一个需要处理的数据对象,有参数,无返回值
Consumer.andThen(Consumer<? super T> after) 接收一个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); };
}
}
例子
public static void main(String[] args) {
consumer("我们是一只小小的鸟, 鸟呀!", s -> {
System.out.println("处理后字符串:" + s.replace("鸟", "人"));
});
}
public static void consumer(String s1, Consumer<String> s2) {
System.out.println("原始字符串:"+ s1);
s2.accept(s1);
s2.andThen(s2);
}
Function
输入T输出R
接受一个输入参数,返回一个结果
R apply(T t)
有参数,有返回值
compose()
先调用compose,在执行调用者
andThen
先执行调用者,在执行andThen
/**
* Represents a function that accepts one argument and produces a result.
*
* <p>This is a <a href="package-summary.html">functional interface</a>
* whose functional method is {@link #apply(Object)}.
*
* @param <T> the type of the input to the function
* @param <R> the type of the result of the function
*
* @since 1.8
*/
@FunctionalInterface
public interface Function<T, R> {
/**
* Applies this function to the given argument.
*
* @param t the function argument
* @return the function result
*/
R apply(T t);
/**
* Returns a composed function that first applies the {@code before}
* function to its input, and then applies this 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 input to the {@code before} function, and to the
* composed function
* @param before the function to apply before this function is applied
* @return a composed function that first applies the {@code before}
* function and then applies this function
* @throws NullPointerException if before is null
*
* @see #andThen(Function)
*/
default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
Objects.requireNonNull(before);
return (V v) -> apply(before.apply(v));
}
/**
* 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
*
* @see #compose(Function)
*/
default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {
Objects.requireNonNull(after);
return (T t) -> after.apply(apply(t));
}
/**
* Returns a function that always returns its input argument.
*
* @param <T> the type of the input and output objects to the function
* @return a function that always returns its input argument
*/
static <T> Function<T, T> identity() {
return t -> t;
}
}
例子
public class Test3 {
private static void method_andThen(Function<String, String> f1, Function<String, String> f2) {
String apply = f1.andThen(f2).apply("先执行调用者;第二章:");
System.out.println(apply);
}
private static void method_compose(Function<String, String> f1, Function<String, String> f2) {
String apply = f1.compose(f2).apply("先调用compose;第二章:");
System.out.println(apply);
}
public static void main(String[] args) {
numberToString((s) -> String.valueOf(s));
// 第二章:天下皆知美之为美 斯恶已
method_andThen(s -> s += "天下皆知美之为美 ", s -> s += " 斯恶已");
// 第二章:斯恶已 天下皆知美之为美
method_compose(s -> s += " 天下皆知美之为美 ", s -> s += "斯恶已");
// 输入对象就是输出对象
Object apply = Function.identity().apply("test");
System.out.println(apply);
}
/**
* 将数字转换为String类型
* @param function
*/
private static void numberToString(Function<Number, String> function) {
String apply = function.apply(12);
System.out.println("转换结果:" + apply);
}
}
Predicate
断定型接口
接收参数T,返回boolean,用来确定T类型参数是否满足某约束,并返回boolean值
处理集合的过滤条件
@FunctionalInterface
public interface Predicate<T> {
/**
* 具体过滤操作 需要被子类实现.
* 用来处理参数T是否满足要求,可以理解为 条件A
*/
boolean test(T t);
/**
* 调用当前Predicate的test方法之后再去调用other的test方法,相当于进行两次判断
* 可理解为 条件A && 条件B
*/
default Predicate<T> and(Predicate<? super T> other) {
Objects.requireNonNull(other);
return (t) -> test(t) && other.test(t);
}
/**
* 对当前判断进行"!"操作,即取非操作,可理解为 ! 条件A
*/
default Predicate<T> negate() {
return (t) -> !test(t);
}
/**
* 对当前判断进行"||"操作,即取或操作,可以理解为 条件A ||条件B
*/
default Predicate<T> or(Predicate<? super T> other) {
Objects.requireNonNull(other);
return (t) -> test(t) || other.test(t);
}
/**
* 对当前操作进行"="操作,即取等操作,可以理解为 A == B
*/
static <T> Predicate<T> isEqual(Object targetRef) {
return (null == targetRef)
? Objects::isNull
: object -> targetRef.equals(object);
}
}
举例
public class TestPredicate {
public static void main(String[] args) {
Predicate<String> predicate = (s) -> s.length() > 5;
boolean r = predicate.test("12346");
// true
System.out.println(r);
// 在Stream中使用
List<User> userList = initUserData();
// User{name='狗', age='5'}
// User{name='乌龟', age='200'}
userList.stream().filter(u -> u.getAge() >= 5).forEach(System.out::println);
}
public static List<User> initUserData() {
List<User> userList = new ArrayList<>();
userList.add(new User("猫", 2));
userList.add(new User("狗", 5));
userList.add(new User("乌龟", 200));
return userList;
}
static class User {
private String name;
private Integer age;
public User(String name, Integer age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public Integer getAge() {
return age;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age='" + age + '\'' +
'}';
}
}
}
Supplier
提供数据的函数式接口
生产数据
T get();
每个调用都会新创建一个对象
@FunctionalInterface
public interface Supplier<T> {
/**
* Gets a result.
*
* @return a result
*/
T get();
}
举例
public class TestSupplier {
public static void main(String[] args) {
Supplier<User> user = User::new;
User user1 = user.get();
User user2 = user.get();
// 1747585824
System.out.println(user1.hashCode());
// 1023892928
System.out.println(user2.hashCode());
}
static class User {
private String name;
private Integer age;
public User() {}
public String getName() {
return name;
}
public Integer getAge() {
return age;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age='" + age + '\'' +
'}';
}
}
}
网友评论