Java Advanced — функциональный интерфейс

1. Функциональный интерфейс

Функциональный интерфейс в Java означает: интерфейс с одним и только одним абстрактным методом. Интерфейс может содержать другие методы (по умолчанию, статические, частные).

Функциональный интерфейс — это интерфейс, подходящий для сценариев функционального программирования. Воплощением функционального программирования на Java является Lambda, поэтому функциональные интерфейсы — это интерфейсы, которые может использовать Lambda.
Только гарантируя, что в интерфейсе есть один и только один абстрактный метод, Lambda в Java может быть выведена плавно.

Синтаксический сахар:

“语法糖”是指使用更加方便,但是原理不变的代码语法。例如在遍历集合时使用的for-each语法,
其实底层的实现原理仍然是迭代器,这便是“语法糖”。从应用层面来讲,java中的Lambda可以
被当做是匿名内部类的 “语法糖”,但是二者在原理上是不同的。

аннотация:

@Override注解
检查方法是否为重写的方法
    是:编译成功
    否:编译失败

@FunctionalInterface注解
作用:可以检查接口是否是一个函数式接口
    是:编译成功
    否:编译失败(接口中没有抽象方法或者接口中的抽象方法多于1个)

2. Лямбда-выражение

1. Особенности Лямбды:

延迟加载,即满足条件才会执行,不满足条件就不执行。

2. Предварительные условия для использования Lambda:

必须存在函数式接口

3.Лямбда-выражение как параметр метода.

Независимо от принципа реализации, лямбда-выражения в Java можно рассматривать как замену анонимных внутренних классов.

Если параметр метода является типом функционального интерфейса, вместо него можно использовать лямбда-выражение.

Использование лямбда-выражений в качестве параметров метода фактически означает использование функциональных интерфейсов в качестве параметров метода.

例如java.lang.Runnable接口就是一个函数式接口,
假设有一个startThread方法使用该接口作为参数,那么就可以使用Lambda进行传参。
这种情况其实和Thread类的构造方法参数为Runnable没有本质区别。

Предварительные условия для использования лямбда-выражений в качестве параметров:

方法的参数是函数式接口

4. Лямбда-выражение как возвращаемое значение метода.

Если тип возвращаемого значения метода является функциональным интерфейсом, то он может напрямую возвращать лямбда-выражение.

Когда вам нужно использовать метод для получения объекта типа интерфейса java.util.Comparator в качестве сортировщика, вы можете вызвать этот метод для его получения.Код выглядит следующим образом:

public static Comparator<String> getComparator(){
    //方法的返回值类型是一个接口,那么我们可以返回这个接口的匿名内部类
	//        return new Comparator<String>() {
	//            @Override
	//            public int compare(String o1, String o2) {
	//                //排序规则:按照字符串的降序排序
	//                return o2.length() - o1.length();
	//            }
	//        };

    //方法的返回值类型是一个函数式接口,所以可以返回一个Lambda表达式
	//        return (String o1, String o2)->{
	//            //排序规则:按照字符串的降序排序
	//            return o2.length() - o1.length();
	//        };

    //优化Lambda
    //参数的数据类型可以省略:String
    //方法体只有一条语句,return可以省略,{}和;可以省略
    return (o1, o2)->o2.length() - o1.length();
}

3. Часто используемые функциональные интерфейсы

1. Интерфейс поставщика

Интерфейс java.util.function.Supplier содержит только один метод без параметров: T.get().

Используется для получения данных объекта типа, указанного универсальным параметром.

Интерфейс поставщика называется «производственным интерфейсом». Если вы укажете общий тип интерфейса, то какой тип данных будет создан методом get в интерфейсе.

2.Пользовательский интерфейс

2.1 java.util.function.Consumer
Этот интерфейс является полной противоположностью интерфейса поставщика. Он не создает данные, а потребляет их, а тип его данных определяется дженериками.

Интерфейс Consumer содержит абстрактный метод void Accept(T t), который означает использование данных указанного универсального типа.

Интерфейс Consumer — это интерфейс потребителя. Независимо от того, какой тип указан в универсальном типе, вы можете использовать метод Accept для использования того или иного типа данных. Что касается удельного потребления (использования), то его необходимо настроить (например, выпуск, расчет и т. д.).

2.2 Метод по умолчанию и затем потребительского интерфейса

Функция: требуются два потребительских интерфейса. Вы можете объединить два потребительских интерфейса вместе, а затем использовать данные.

Например:

Consumer<String> con1
Consumer<String> con2
String s = "java";
con1.accept(s);
con2.accept(s);

使用andThen进行优化:连接两个Consumer接口,再对数据进行消费
//谁写在前面,谁就先进行消费
//con1先进行消费,然后是con2
con1.andThen(con2).accept(s);

3. Интерфейс предикатов

Функция: оценивать данные определенного типа данных и возвращать в результате логическое значение.

Интерфейс Predicate содержит абстрактный метод:

boolean test<T t>:用来对指定数据类型数据进行判断的方法
    结果:
        符合条件:返回true
        不符合条件:返回false

Логические выражения: условия, которые могут связывать несколько суждений.

&&:与运算符,有false则false
||:或运算符,有true则true
!:非运算符:true则false;false则true

3.1 и метод

В интерфейсе Predicate есть метод and, который представляет отношение AND и также может использоваться для соединения двух условий оценки.

default Predicate<T> and(Predicate<? super T> other){
    Objects.requireNonNull(other);
    return (t) -> test(t) && other.test(t);
}

可见and方法内部的两个判断条件,也是使用&&运算符连接起来的

3.2 или метод

В интерфейсе Predicate есть метод or, который представляет отношение or и также может использоваться для соединения двух условий оценки.

default Predicate<T> or(Predicate<? super T> other){
    Objects.requireNonNull(other);
    return (t) -> test(t) || other.test(t);
}

可见or方法内部的两个判断条件,也是使用||运算符连接起来的

3.3 отрицательный метод

В интерфейсе Predicate есть метод negate, который означает отрицание.

default Predicate<T> negate(){
    return (t) -> !test(t);
}

4. Функциональный интерфейс

1. Интерфейс функции и его абстрактные методы.

Интерфейс java.util.function.Function<T,R> используется для получения данных одного типа на основе данных другого типа. Первый
называется предварительным условием, а второй — постусловием. То есть этот интерфейс используется для [преобразования типов].

Основным абстрактным методом в интерфейсе Function является: R apply(T t), который получает результат типа R на основе параметров типа T. Например: преобразовать тип String в тип Integer.

2. Метод по умолчанию, а затем в интерфейсе функции.

Функция: выполнять совмещенные операции

нуждаться:

把String类型的“123”转换为Integer,把转换后的结果加10

把增加之后的Integer类型的数据,转换为String类型

анализировать:

转换了两次:

第一次是把String类型转换为Integer类型
    可以使用Function<String Integer> fun1
        Integer i = fun1.apply("123") + 10;
        
第二次是把Integer类型转化为String类型
    可以使用Function<Integer, String> fun2
        String s = fun2.apply(i);
        
可以使用andThen方法,把两次转换组合在一起使用
    String s = fun1.andThen(fun2).apply("123");
    fun1先调用apply方法,把字符串转换为Integer
    fun2再调用apply方法,把Integer转换为字符串

Guess you like

Origin blog.csdn.net/weixin_42214237/article/details/122847011