JAVA基础9-函数式接口学习笔记

函数式接口

标注为FunctionalInterface的接口被称为函数式接口,该接口只能有一个自定义方法,但是可以包括从object类继承而来的方法。如果一个接口只有一个方法,则编译器会认为这就是一个函数式接口。是否是一个函数式接口,需要注意的有以下几点:

  1. 该注解只能标记在”有且仅有一个抽象方法”的接口上。
  2. JDK8接口中的静态方法和默认方法,都不算是抽象方法。
  3. 接口默认继承java.lang.Object,所以如果接口显示声明覆盖了Object中方法,那么也不算抽象方法。
  4. 该注解不是必须的,如果一个接口符合”函数式接口”定义,那么加不加该注解都没有影响。加上该注解能够更好地让编译器进行检查。如果编写的不是函数式接口,但是加上了@FunctionInterface,那么编译器会报错。
  5. 在一个接口中定义两个自定义的方法,就会产生Invalid ‘@FunctionalInterface’ annotation; FunctionalInterfaceTest is not a functional interface错误。

Function接口

接口说明

/**
     * 一个入参,和一个返回参数
     */
    R apply(T t);

    /**
     * 返回一个先执行before函数对象apply方法再执行当前函数对象apply方法的函数对象
     */
    default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
        Objects.requireNonNull(before);
        return (V v) -> apply(before.apply(v));
    }

    /**
     * 返回一个先执行当前函数对象apply方法再执行after函数对象apply方法的函数对象。
     */
    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;
    }

Java已有接口

Arrays::asList

应用

package com.lin.function.function;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.Function;

public class TestFunction {
	public static void main(String[] args) {
		Function<Integer,Integer> func1 = e->e*2;
		Function<Integer,Integer> func2 = e->e+2;
		System.out.println(func2.andThen(func1).apply(3));
		System.out.println(func2.compose(func1).apply(3));
		List<String[]> list = new ArrayList<String[]>();
		String[] a = {"a1","a2","a3"};
		String[] b = {"b1","b2"};
		String[] c = {"c1","c2","c3"};
		list.add(a);
		list.add(b);
		list.add(c);
		list.stream().map(Arrays::asList).forEach(System.out::println);
	}
}

扩展

Function接口是一个入参,一个出参。
1) 当入参和出参为基本类型int、long和double,会新增12种扩展
① 入参为基本类型,出参为自定义
IntFunction:入参为int,出参自定义,以此类推,LongFunction和DoubleFunction
② 入参为自定义,出参为基本类型
ToIntFunction:出参为int,入参自定义,以此类推,ToLongFunction和ToDoubleFunction
③ 入参和出参都为基本类型
IntToDoubleFunction:入参为int,出参为double,以此类推IntToLongFunction、LongToIntFunction、LongToDoubleFunction、DoubleToIntFunction、DoubleToLongFunction
2) 当入参为2个,出参为1个,新增4种扩展
BiFunction:入参2个,出参1个
ToIntBiFunction:入参2个自定义,出参为int,以此类推ToIntLongFunction和ToDoubleBiFunction

Predicate

接口说明

/**
     * 一个入参,出参为boolean类型
     */
    boolean test(T t);

    /**
     *且操作,既满足A也满足B条件
     */
    default Predicate<T> and(Predicate<? super T> other) {
        Objects.requireNonNull(other);
        return (t) -> test(t) && other.test(t);
    }

    /**
     *取反操作 为true则返回false
     */
    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);
    }

    /**
     *静态方法,判定是否相等
     */
    static <T> Predicate<T> isEqual(Object targetRef) {
        return (null == targetRef)
                ? Objects::isNull
                : object -> targetRef.equals(object);
    }

Java已有接口

Collection::isEmpty

应用

package com.lin.function.predicate;
import java.util.function.Predicate;

public class TestPredicate {
	public static void main(String[] args) {
		Predicate<Integer> p1 = e->e<10;//小于10的条件
		Predicate<Integer> p2 = e->e>5;//大于5的条件
		System.out.println(p1.and(p2).test(8));
		System.out.println(p1.or(p2).test(8));
		System.out.println(p1.negate().test(8));
	}
}

扩展

Predicate接口是一个入参,出参boolean。
1) 当入参为基本类型int、long和double,会新增3种扩展
IntPredicate表示入参为int。以此类推LongPredicate和DoublePredicate。
2) 当入参为2个时,会新增1种扩展
BiPredicate。

Consumer接口

接口说明

/**
     一个入参,没有出参接口
     */
    void accept(T t);

    /**
     * 返回一个先执行当前函数对象apply方法再执行after函数对象apply方法的函数对象。
     */
    default Consumer<T> andThen(Consumer<? super T> after) {
        Objects.requireNonNull(after);
        return (T t) -> { accept(t); after.accept(t); };
    }

Java已有接口

System.out::println

应用

package com.lin.function.consumer;
import java.util.function.Consumer;

public class TestConsumer {
	public int a = 1;
	public static void main(String[] args) {
		Consumer<TestConsumer> consumer1 = e-> e.a = e.a+1;
		Consumer<TestConsumer> consumer2 = e-> e.a = e.a*2;
		TestConsumer old = new TestConsumer();
		old.a = 1;
		consumer1.accept(old);
		System.out.println(old.a);
		consumer1.andThen(consumer2).accept(old);
		System.out.println(old.a);
	}
}

扩展

Consumer接口是一个入参,没有出参。
1) 当入参为基本类型int、long和double,会新增3种扩展
IntConsumer,入参为int。以此类推,LongConsumer和DoubleConsumer。
2) 当入参2个,分别是一个泛型和一个基本类型int、long和double,会新增3种扩展
ObjIntConsumer,入参为泛型T和int。以此类推,ObjLongConsumer和ObjDoubleConsumer。
3) 当入参2个,分别都是泛型,会新增1种扩展
BiConsumer,入参为2个,都为泛型。

Supplier

接口说明

/**
     * 一个泛型出参,没有入参
     */
    T get();

Java已有接口

Instant::now

应用

package com.lin.function.supplier;
import java.util.function.Supplier;

public class TestSupplier {
	public static void main(String[] args){
		Supplier<String> sup = ()->"abc";
		System.out.println(sup.get());
	}
}

扩展

Supplier是一个只有出参,没有入参接口。
当出参是基本数据类型boolean、int、long、double时,有4种扩展分别是BooleanSupplier、IntSupplier、LongSupplier和DoubleSupplier。

UnaryOperator

接口说明

UnaryOperator接口继承了Function接口,也是一个入参一个出参。特殊的地方是UnaryOperator接口的入参和出参是同一类型。

public interface UnaryOperator<T> extends Function<T, T>

/**
  * 入参和出参都是同一个类型
*/
T apply(T t);

Java已有接口

String::toLowerCase

应用

package com.lin.function.unaryOperator;
import java.util.function.UnaryOperator;

public class TestUnaryOperator {
	public static void main(String[] args) {
		UnaryOperator<Integer> uop1 = e-> e+3;
		UnaryOperator<Integer> uop2 = e-> e*2;
		System.out.println(uop1.andThen(uop2).apply(2));
		System.out.println(uop1.compose(uop2).apply(2));
		System.out.println(UnaryOperator.identity().apply(2));
	}
}

扩展

UnaryOperator接口是一个入参和一个出参,入参和出参是同一种类型。当类型为基本类型int、long和double时,有三种扩展,分别是IntUnaryOperator、LongUnaryOperator和DoubleUnaryOperator。

BinaryOperator

接口说明

BinaryOperator接口继承BiFunction接口,BiFunction接口是Function接口的扩展,有2个入参和1个出参。BinaryOperator接口是BiFunction接口的特殊情况,当入参和出参的数据类型相同时,就是BinaryOperator。

public interface BinaryOperator<T> extends BiFunction<T,T,T>

除了继承BiFunction接口里面的方法外,BinaryOperator接口还实现一下2个静态方法:

/**
  * 接收一个比较实现,获取最小值。
*/
public static <T> BinaryOperator<T> minBy(Comparator<? super T> comparator) {
   Objects.requireNonNull(comparator);
   return (a, b) -> comparator.compare(a, b) <= 0 ? a : b;
}


/**
  *接收一个比较实现,获取最大值。
*/
public static <T> BinaryOperator<T> maxBy(Comparator<? super T> comparator) {
    Objects.requireNonNull(comparator);
    return (a, b) -> comparator.compare(a, b) >= 0 ? a : b;
}

Java已有接口

BigInteger::add

应用

package com.lin.function.binaryOperator;
import java.util.function.BinaryOperator;

public class TestBinaryOperator {
	public static void main(String[] args) {
		BinaryOperator<Integer> addOperator = (a,b)->a+b;
		BinaryOperator<Integer> subOperator = (a,b)->a-b;
		System.out.println(addOperator.apply(4, 2));
		System.out.println(subOperator.apply(4, 2));
		System.out.println(BinaryOperator.maxBy((Integer a, Integer b)->a.compareTo(b)).apply(4, 5));
		System.out.println(BinaryOperator.minBy((Integer a, Integer b)->a.compareTo(b)).apply(4, 5));
	}
}

扩展

BinaryOperator有2个入参和1个出参,而且入参和出参的数据类型一样。如果数据类型为基本类型int、long和double时,有3种扩展,分别是IntBinaryOperator、LongBinaryOperator和DoubleBinaryOperator。

猜你喜欢

转载自blog.csdn.net/linwu_2006_2006/article/details/95033431