java8四大核心函数式接口(模拟实现,全网最通俗易懂)

前言,如果不精通lamda表达式,请观看文章https://blog.csdn.net/wwwwwww31311/article/details/113116327

一、消费者接口

经典案例代码,怎么样,懵逼不?

//结果输出为500
@Test
public void test1 () {
    
    
    consumerTest(500, (x) -> System.out.println(x));
 }
      
public void consumerTest (double money, Consumer<Double> c) {
    
    
    c.accept(money);
}

那么,看一下小编自己的消费者接口模拟实现,为了使大家能够深入理解,我们都会将一个函数式接口的实现分为两步
①构造接口匿名实现类对象然后将其传入相应的方法
②分析方法内部如何运作的

/*
这是消费型接口,有参数,无返回值类型的接口。内置一个accept抽象方法
Consumer<T>:消费型接口(void accept(T t))
 */
@FunctionalInterface
interface Consumer<T>{
    
    
    void accept(T data);
}

public class Test {
    
    

    public void consumerTest(Double money,Consumer<Double> customer){
    
    
         customer.accept(money);
    }

    @Test
    public void test(){
    
    
        //我们先创建一个Consumer接口的匿名接口实现类,然后把它当做参数传入下面的方法consumerTest
        Consumer<Double> doubleConsumer = new Consumer<Double>() {
    
    
            @Override
            public void accept(Double money) {
    
    
                System.out.println("消费者消费:" +money);
            }
        };
        //这个方法内部再调用的是doubleConsumer.accpet
        consumerTest(500.0, doubleConsumer);

        //再用lamda表达式的方式就容易接受了
        consumerTest(500.0,(x) -> System.out.println("消费者消费:" +x));
    }
}

运行结果
在这里插入图片描述

二、供给者接口

令人懵逼的代码

    @Test
    public void test2 () {
    
    
        Random ran = new Random();
        List<Integer> list = supplier(10, () -> ran.nextInt(10));

        for (Integer i : list) {
    
    
            System.out.println(i);
        }
    }

    public List<Integer> supplier(int sum, Supplier<Integer> sup){
    
    
        List<Integer> list = new ArrayList<Integer>();
        for (int i = 0; i < sum; i++) {
    
    
            list.add(sup.get());
        }
        return list;
    }

小编简单翻译后的代码

/*
Supplier<Integer>:就是一个供给类型得接口,只有产出,没人输入,就是只有返回值,没有入参
Supplier<T>:供给型接口(T get())
 */
@FunctionalInterface
interface Supplier<T> {
    
    
    T get();
}

public class Test {
    
    
    //供给者方法实现
    public List<Integer> supplier(int sum, Supplier<Integer> sup){
    
    
        ArrayList<Integer> ls = new ArrayList<>();
        for (int i = 0; i < sum; i++) {
    
    
            ls.add(sup.get());
        }
        return ls;
    }

    @Test
    public void test2(){
    
    
        //我们先创建一个Supplier接口的匿名接口实现类,然后把它当做参数传入下面的方法supplier2
        //suppler2和suppler1唯一看似的不同地方就是get()方法的实现形式不一样(但它们俩get函数的内容是一模一样的)
        Supplier<Integer> s1 = new Supplier<Integer>() {
    
    
            @Override
            public Integer get() {
    
    
                return new Random().nextInt(10);
            }
        };

        List<Integer> supplier2 = supplier(10,s1);
        for (Integer i : supplier2) {
    
    
            System.out.print(i + " ");
        }
        
        //再看lamda表达式写法
        Random random = new Random();
        List<Integer> supplier = supplier(10, () -> random.nextInt(10));
        for (Integer i : supplier) {
    
    
            System.out.print(i + " ");
        }
        System.out.println();
    }
}

运行结果
在这里插入图片描述
三、函数式接口
懵逼的写法

    @Test
    public void test3 () {
    
    
        String s = strOperar(" asdf ", x -> x.substring(0, 2));
        System.out.println(s);
        String s1 = strOperar(" asdf ", x -> x.trim());
        System.out.println(s1);
    }

    public String strOperar(String str, Function<String, String> fun) {
    
    
        return fun.apply(str);
    }

翻译后的写法

/*
函数型接口,输入一个类型得参数,输出一个类型得参数,当然两种类型可以一致
Function<T, R>:函数型接口(R apply(T t))
*/
@FunctionalInterface
interface Function<T, R> {
    
    
    R apply(T t);
}

public class Test {
    
    
    public String strOperar(String str, Function<String,String> fun){
    
    
        return fun.apply(str);
    }

    @Test
    public void test5(){
    
    
        Function<String,String> fun = new Function<String, String>() {
    
    
            @Override
            public String apply(String s) {
    
    
                return s.substring(0,2);
            }
        };
        //s入值是“ab”,相当于将abcdfg作为参数s传入apply方法;
        String s = strOperar("abcdefg",fun);

        //在看一些lamda表达式的写法就不那么蒙蔽了
        String s2 = strOperar("abcdefg",(str) -> str.substring(0,2));
    }
}

运行结果
在这里插入图片描述

四、断言型接口

最后一个不再模拟,看一下标准代码

/*
Predicate<T>:断言型接口(boolean test(T t))
上面就是一个断言型接口,输入一个参数,输出一个boolean类型得返回值
用来判断是否加入集合中,这种结构非常适合做过滤器Filter
*/
public class Test {
    
    
     public List<Integer> filterInt(List<Integer> list, Predicate<Integer> pre){
    
    
         List<Integer> ls = new ArrayList<>();
         for (Integer l : list) {
    
    
             if(pre.test(l)){
    
    
                 ls.add(l);
             }
         }
         return ls;
     }

    @org.junit.jupiter.api.Test
    public void test7(){
    
    
        List<Integer> ls =  new ArrayList<>();
        ls.add(1);
        ls.add(2);
        ls.add(3);
        ls.add(4);
        ls.add(5);
        List<Integer> lists = filterInt(ls, x -> (x > 2));
        for (Integer list : lists) {
    
    
            System.out.print(list + " ");
        }
    }

}

猜你喜欢

转载自blog.csdn.net/wwwwwww31311/article/details/113250259