Java中的函数式接口和lambda表达式(一)

6 篇文章 0 订阅

函数式接口

@FunctionalInterface

jdk中的英文注解

  • An informative annotation type used to indicate that an interface
  • type declaration is intended to be a functional interface as
  • defined by the Java Language Specification.
    在Java中只要有接口@FunctionalInterface代表他是 一个函数式接口。
    Conceptually, a functional interface has exactly one abstract
  • method. Since {@linkplain java.lang.reflect.Method#isDefault()
  • default methods} have an implementation, they are not abstract. If
  • an interface declares an abstract method overriding one of the
  • public methods of {@code java.lang.Object}, that also does
  • not count toward the interface’s abstract method count
  • since any implementation of the interface will have an
  • implementation from {@code java.lang.Object} or elsewhere.
    1.这个接口有且只能由一个抽象方法
    2.jdk8之后可以在接口中实现方法了,可以通过default声明进行实现,但是他们不归属于抽象方法行列中
    3.像重写超级父类Object中的public方法也是不算是抽象方法
    例子:
    下面展示一些 内联代码片
@FunctionalInterface
public interface MyInterface {
    void test();
    //其满足了复写父类的抽象方法,其也认为其只有一个抽象类
    String toString();
}
@FunctionalInterface
public interface MyInterface {
    void test();
    //其满足了复写父类的抽象方法,其也认为其只有一个抽象类
    String toString();
}

但是下面这个就会报错

@FunctionalInterface
public interface MyIntestfaceTest {
    void test();
    String myString();
}

@FunctionalInterface
public interface MyIntestfaceTest {
    void test();
    String myString();
}

报错信息:Multiple non-overriding abstract methods found in interface com.curry.jdk8.MyIntestfaceTest意思是有多个抽象方法。

However, the compiler will treat any interface meeting the * definition of a functional interface as a functional interface * regardless of whether or not a {@code FunctionalInterface} * annotation is present on the interface declaration.

4.在编译过程中如果不加@FunctionalInterface注解时,如果你的类符合函数式接口的要求,在编译时还是按照函数式接口编译。*

Note that instances of functional interfaces can be created with
  • lambda expressions, method references, or constructor references.

5.函数式接口可以通过三种方式进行创建lambda表达式,方法引用、构造函数引用(这篇文章主要先通过lambda表达式,其他两种后续文章简绍)

jdk中几种比较常用的函数式接口

1.Consumer
其只有输入参数无返回值
应用:
下面展示一些 jdk中是如何使用的

/**
 * @author curry
 * @Date 2022/1/18 9:43
 * @since 1.0.0
 */
public class LamdaTest1 {
    public static void main(String[] args) {
        System.out.println("开始了..................");
        // System.out.println(System.getProperty("file.encoding"));
        List<Integer> list = Arrays.asList(1,2,3,4,5,6);
        //传统的迭代方式一
        for(int i = 0; i < list.size(); i++) {
            System.out.println(list.get(i));
        }
        System.out.println("------------------");
        //传统迭代方式二
        for (Integer i : list) {
            System.out.println(i);
        }
        System.out.println("----------------");
        // 内部类迭代
        list.forEach(new Consumer<Integer>() {
            @Override
            public void accept(Integer integer) {
                System.out.println(integer);
            }
        });
        System.out.println("--------------------");
        //lambda使用
       list.forEach(i -> System.out.println(i));
        System.out.println("--------------------");
        //方法引用使用
        list.forEach(System.out::println);

    }
}

2.Function<T, R>,BiFunction<T, U, R>
既有参数又有返回值
改变之前java只是用于值进行传递,可以通过行为进行传递,将实际行为通过回调函数进行处理
下面展示一些 自己如何用代码

/**
 * @author curry
 * @Date 2022/1/19 10:24
 * @since 1.0.0
 */
/*
    函数式接口Function并不是只管值,还在意执行行为
 */
public class FunctionTest {
    public static void main(String[] args) {
        FunctionTest functionTest = new FunctionTest();
        //传统的处理加,乘这种行为是提前已经写好了
        System.out.println(functionTest.add(9));
        System.out.println(functionTest.mul(9));
        System.out.println("传统的调用方式");
        //函数接口方式  是您实际要用的时候传递过去的
        System.out.println(functionTest.compute(9,a->{return 2+a;}));
        System.out.println(functionTest.compute(9,a->a*2));
        System.out.println("高阶函数式调用方式");
    }
    //高阶函数 两个参数可以用BiFunction
    public int compute(int a, Function<Integer,Integer> function) {
        return function.apply(a);
    }
    public int add(int a) {
        return a+2;
    }
    public int mul(int a){
        return a*2;
    }
}

实际jdk中哪里用到了,如:流stream中map()底层用到的就是Function

public class InterfaceObject {
    public static void main(String[] args) {

        List<String> list1 = Arrays.asList("lee","curry","lee_curry");
        //stream  map中有个函数式接口 用lambda处理
        list1.stream().map(item -> item.toUpperCase()).forEach(item -> System.out.println(item));

        //stream map中的函数式接口  用方法引用处理  stream中有fileter(Predicate)
        list1.stream().map(String::toUpperCase).forEach(item -> System.out.println(item));
    }
}

在Function中有两个默认实现方法的作用区分:compose()andThen()
下面展示一些 内联代码片

/**
 * @author curry
 * @Date 2022/1/19 11:23
 * @since 1.0.0
 */
public class FunctionTest1 {
    public static void main(String[] args) {
        FunctionTest1 t = new FunctionTest1();
        System.out.println(t.compute(2,v -> v*3,v->v*v)); //12

        System.out.println(t.compute2(2,v -> v*3,v->v*v)); // 36
    }
    public int compute(int a, Function<Integer,Integer> function1, Function<Integer,Integer> function2) {
        return function1.compose(function2).apply(a);//先参数函数再执行调用的
    }
    public int compute2(int a, Function<Integer,Integer> function1, Function<Integer,Integer> function2) {
        return function1.andThen(function2).apply(a);//先执行调用函数再执行参数函数
    }
}

BiFunction<T, U, R>作用类似
下面展示一些 内联代码片


/**
 * @author curry
 * @Date 2022/1/19 13:21
 * @since 1.0.0
 */
public class Person {
    private int age;
    private String name;

    public Person(int age, String name) {
        this.age = age;
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
/**
 * @author curry
 * @Date 2022/1/19 13:20
 * @since 1.0.0
 */
public class FunctionTest2 {
    public static void main(String[] args) {
        Person p1 =new Person(20, "zhangsan");
        Person p2 =new Person(30, "lisi");
        Person p3 =new Person(40, "wangwu");

        List<Person> persons = Arrays.asList(p1,p2,p3);
        FunctionTest2 t = new FunctionTest2();
        List<Person> peopleResult = t.getPersonsByUsername("lisi",persons);
        peopleResult.forEach(person -> System.out.println(person.getName()));
        System.out.println("单参数接口函数");

        List<Person> peopleResult1 = t.getPersonsByage(22,persons);
        peopleResult1.forEach(person -> System.out.println(person.getName()));
        System.out.println("双参数接口函数");
        //filter有个Predicate函数接口
        List<Person> peopleResult2 = t.getPersonsByage1(32,persons,(myAge,myPersons) -> myPersons.stream().filter(person -> person.getAge()>myAge).collect(Collectors.toList()));
        peopleResult2.forEach(person -> System.out.println(person.getName()));
        System.out.println("双参数接口函数,将行为调用的时候处理");
    }
    public List<Person> getPersonsByUsername (String username,List<Person> persons) {
        return persons.stream().filter(person -> person.getName().equals(username)).collect(Collectors.toList());
    }
    //没有实现将规则给实际应用的时候调用
    public List<Person> getPersonsByage(int age,List<Person> persons) {
        BiFunction<Integer,List<Person>,List<Person>> biFunction = (byAge,personResult)->personResult.stream().filter(person -> person.getAge()>24).collect(Collectors.toList());
        return biFunction.apply(age,persons);
    }
    //用函数式接口就可以实现
    public List<Person> getPersonsByage1(int age,List<Person> persons,BiFunction<Integer,List<Person>,List<Person>> biFunction) {
        return biFunction.apply(age,persons);
    }
}

详解请看下篇文章

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值