java8学习(三)函数式接口

java8学习(三)函数式接口

1. 函数式接口 的产生

在学习完Lambda表达式之后得到结论:使用Lambda表达式的前提是需要有函数式接口,而Lambda表达式使用时不关心接口名,抽象方法名。只关心抽象方法的参数列表和返回值类型。因此为了让我们使用Lambda表达式更加的方便,在JDK中提供了大量常用的函数式接口。

2.函数式接口介绍及使用

在JDK中帮我们提供的有函数式接口,主要是在 java.util.function 包中。

2.1 Supplier

无参有返回值的接口,对于的Lambda表达式需要提供一个返回数据的类型。
接口:

@FunctionalInterface
public interface Supplier<T> {

    /**
     * Gets a result.
     *
     * @return a result
     */
    T get();
}

使用案例:

public class SupplierFunction {
    public static void main(String[] args) {
        funcSupplier(()->{
            //创建一个数组
            Integer arrs [] = {1, 2, 3, 6, 10, 50, 30, 22, 9};
            //对数组进行自然顺序排序
            Arrays.sort(arrs);
            //数组得最后一个下标对应得数据即为最大值
            return arrs[arrs.length-1];
        });

    }

    /**
     * 获取最大值
     * @param supplier
     */
    private static void funcSupplier(Supplier<Integer> supplier){
        Integer max = supplier.get();
        System.out.println("最大值为:"+max);
    }
}

控制台输出:

最大值为:50

2.2 Consumer

有参无返回值得接口,前面介绍的Supplier接口是用来生产数据的,而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); };
   }
}

使用accept()

public class ConsumerFunction {
    public static void main(String[] args) {
        funConsumer(s -> {
            System.out.println("得到参数"+s+"转换为小写====>"+s.toLowerCase());
        });
    }

    private static void funConsumer(Consumer<String> consumer){
        consumer.accept("Hello World");
    }
}

控制台输出:

得到参数Hello World转换为小写====>hello world

默认andThen 方法:
如果一个方法的参数和返回值全部是Consumer类型,那么就可以实现效果,消费一个数据的时候,首先做一个操作,然后再做一个操作,实现组合,而这个方法就是Consumer接口中的default方法andThen方法。
使用案例:

public class ConsumerFunction {
    public static void main(String[] args) {
        funConsumerAndThen(s1->{
            System.out.println("得到参数"+s1+"转换为小写====>"+s1.toLowerCase());
        },s2->{
            System.out.println("得到参数"+s2+"转换为大写====>"+s2.toUpperCase());
        });
    }

    private static void funConsumerAndThen(Consumer<String> c1,Consumer<String> c2){
        c1.andThen(c2).accept("Hello World");
    }
}

控制台输出:

得到参数Hello World转换为小写====>hello world
得到参数Hello World转换为大写====>HELLO WORLD

2.3 Function

有参有返回值的接口,Function接口是根据一个类型的数据得到另一个类型的数据,前者称为前置条件,后者称为后置条件。有参数有返回值。
接口:

@FunctionalInterface
public interface Function<T, R> {

   R apply(T t);

   default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
       Objects.requireNonNull(before);
       return (V v) -> apply(before.apply(v));
   }

   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;
   }
}

使用R apply(T t);

public static void main(String[] args) {
        testFunction(s-> String.valueOf(s));
    }
    /**
     * 将数字转为String
     * @param f
     */    
private static void testFunction(Function<Integer,String> f){
        String apply = f.apply(123);
        System.out.println("apply:"+apply);
    }    

控制台输出:

apply:123

使用andThen(Function<? super R, ? extends V> after)方法
将结果应用与after上,是一个组合操作

public static void main(String[] args) {
     testFunction2(s-> Integer.parseInt(s),s2-> String.valueOf(s2+1));
 }
private static void testFunction2(Function<String,Integer> f,Function<Integer,String> f2){
     String apply = f.andThen(f2).apply("99");
     System.out.println(apply);
 }

控制台输出:

100

使用compose(Function<? super V, ? extends T> before)

先执行before,然后用于其他操作,与andThen相反

    public static void main(String[] args) {
     testFunction3(s->Integer.parseInt(s), s2->String.valueOf(s2+1));
 }
     private static void testFunction3(Function<String,Integer> f,Function<Integer,String> f2){
     Integer apply = f.compose(f2).apply(99);
     System.out.println("testFunction3==>apply:"+apply);
 }

控制台输出:

testFunction3==>apply:100

静态方法identity则是,输入什么参数就返回什么参数。

2.4 Predicate

有参数且返回值为boolean的接口
接口:

@FunctionalInterface
public interface Predicate<T> {

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

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

    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);
    }
}

使用test:

public static void main(String[] args) {
        funPredicate(msg -> ms
        g.length() > 3 ,"mx");
    }
    private static void funPredicate(Predicate<String> predicate,String msg){
        boolean b = predicate.test(msg);
        System.out.println("传入的参数长度大于三是否成立" + b);
    }

使用 and or negate 方法

public static void main(String[] args) {
        funPredicateTest(
                p1m->p1m.length()>2,
                p2m->p2m.startsWith("H"),
                "Hello"
                );
    }

    private static void funPredicateTest(Predicate<String> p1,Predicate<String> p2,String msg){
        boolean b = p1.and(p2).test(msg);
        System.out.println(msg+":长度大于2并且首字母是是否成立:" + b);
        boolean b2 = p1.or(p2).test(msg);
        System.out.println(msg+":长度大于2或者首字母是是否成立:" + b2);
        //取反
        boolean b3 = p2.negate().test(msg);
        System.out.println(msg+":首字母不包括H,是否成立:" + b3);
    }

控制台输出:

Hello:长度大于2并且首字母是是否成立:true
Hello:长度大于2或者首字母是是否成立:true
Hello:首字母不包括H,是否成立:false

使用isEqual方法

    public static void main(String[] args) {
        String s="Hello";
        System.out.println(Predicate.isEqual(s).test("Hello"));
    }

控制台输出

true

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值