Java8新特性之函数式接口

函数式接口

函数式接口是具有一个抽象方法的接口。

不能使用以下类型的方法来声明一个函数式接口:

  • 默认方法
  • 静态方法
  • 从Object类继承的方法

一个函数式接口可以重新声明Object类中的方法。该方法不被视为抽象方法。Comparator接口有两个抽象方法:compare()equals()equals()方法是Object类中的equals()方法的重新声明。

@FunctionalInterface
interface Comparator<T>{
    int compare(T o1, T o2);
    boolean equals(Object obj);
}

@FunctionalInterface

@FunctionalInterface注解定义java.lang包。使用它来标记一个函数式接口。

@FunctionalInterface在非函数式接口或其他类型(如类)上注释,则会发生编译时错误。

具有一个抽象方法的接口仍然是一个功能接口,即使我们不用@FunctionalInterface注释。

通用函数式接口

使用类型参数与函数式接口定义通用函数式接口:

interface Calculator<T> {
    int add(T a, T b);
}

使用抽象通用方法定义非通用函数式接口:

@FunctionalInterface
public interface Processor {
   <T> void  process(T[] list);
}

java.util.function包

Function<T,R>

作用:接受类型T的参数并返回类型R的结果的函数。

Function<T,R>接口的6个特殊化:

  • IntFunction
  • LongFunction
  • DoubleFunciton
  • ToIntFunction
  • ToLongFunction
  • ToDoubleFunction

IntFunction、LongFunction、DoubleFunction 分别以 int、long、double类型作为参数,以 R 作为返回值类型。

ToIntFunction、ToLongFunction、ToDoubleFunction 以T作为参数类型,分别返回int、long、double类型。

常用方法:

R apply(T t);
//创建一个Function,调用当前函数和指定的函数后得到结果
default <V> Function<T,V> andThen(Function<? super  R,? extends V> after)
//创建一个Function,该函数调用指定的函数,然后调用当前函数并返回结果
default <V> Function<V,R> compose(Function<? super  V,? extends T> before)
//创建一个返回其参数的函数
static <T> Function<T,T> identity()
BiFunction<T,U,R>

作用:接受类型T和U的两个参数,并返回类型R的结果。

BiFunction<T,U,R>接口的3个特殊化:

  • ToIntBiFunction<T,U>
  • ToLongBiFunction<T,U>
  • ToDoubleBiFunction<T,U>

ToIntBiFunction<T,U>、ToLongBiFunction<T,U>、ToDoubleBiFunction<T,U> 接受两个参数,以T,U作为参数类型,分别返回int、long、double类型。

常用方法:

int applyAsInt(T t, U u);
Predicate<T>

作用:接受类型T的参数,返回truefalse的布尔类型。

常用方法:

//对给定的参数计算此谓词。
boolean test(T t);
//否定原始谓词的谓词
default  Predicate<T> negate()
//组合两个具有短路逻辑and的谓词
default  Predicate<T> and(Predicate<? super T> other)
//组合了具有短路逻辑或的两个谓词
default  Predicate<T> or(Predicate<?  super T> other)
//返回一个谓词,根据Objects.equals(Object,Object)测试两个参数是否相等
static <T> Predicate<T> isEqual(Object  targetRef)

例:

public class Demo_06_Predicate {
    public static void main(String[] args) {
        //判断num值是否大于2
        Predicate<Integer> p1 = (num)-> num > 2;
        System.out.println(p1.test(10));
        //判断str字符串长度是否大于0且小于10
        Predicate<String> p2 = (str)->str.length() > 0;
        Predicate<String> p3 = (str)->str.length() < 10;
        System.out.println(p2.and(p3).test("hello world!"));
    }
}
BiPredicate<T,U>

作用:接受类型T和U的两个参数,返回truefalse的布尔类型。

Consumer<T>

作用:接受类型T的参数,不返回结果。

BiConsumer<T,U>

作用:接受类型T,U的两个指定参数,不返回结果。

Supplier<T>

定义:Supplier接口也是用来创建对象的,但是不同于 new ,通过调用 get 方法间接调用构造方法创建一个新对象。

作用:返回类型T的值的函数。

UnaryOperator<T>

作用:接受参数并返回相同类型的结果的函数。

BinaryOperator<T>

作用:接受两个参数并返回相同类型的结果。

例:求两个数的最大值

public class Demo_20_BinaryOperator {
    public static void main(String[] args) {
        BinaryOperator<Integer> bo = (a, b) -> {
            return a > b ? a : b;
        };
        System.out.println(bo.apply(10, 30));
    }
}

交叉类型

Java 8引入了一种称为交集类型的新类型。交叉类型是多种类型的交叉。两种类型之间使用Type1 & Type2,以表示类型1,类型2的交集的新类型。

注:交叉类型是解决lambda表达式不能直接赋值非函数式接口类型的一种方式

public class Demo_05 {
    public static void main(String[] args) {
        //为创建一个lambda表达式并赋值给非函数式接口 NonFunction 类型,可使用 & 来创建新的子类型(交叉类型)。
        NoFunction noFunction = (NoFunction & Calculator) ((a, b) -> a * b);
        System.out.println(noFunction);
        //以这种方式,可以使一个lambda表达式可序列化
        Serializable serializable = (Serializable & Calculator) ((a, b) -> a - b);
    }

    @FunctionalInterface
    interface Calculator {
        int calc(int a, int b);
    }

    //非函数式接口
    interface NoFunction {
    }
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

所幸你是例外

你的鼓励将是我创作的最大动力~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值