栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

JAVA函数式接口 与 匿名内部类、Lambda表达式、方法引用

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

JAVA函数式接口 与 匿名内部类、Lambda表达式、方法引用

函数式接口 (Functional Interface)

函数式接口主要指的是只包含一个抽象方法的接口,例如:java.lang.Runnable、java.util.Cpmparator接口等等。

Java8提供@FunctionalInterface注解来定义函数式接口,若定义的接口不符合函数式的规范,则会报错。在Java8中增加了java.util.function包(包内提供了大量的函数式接口):

匿名内部类

没有名字的内部类

语法格式:
父类/接口类型 引用变量名 = new 父类/接口类型(参数列表){
方法的重写
};

Lambda表达式

Lambda表达式是实现函数式接口的重要方式,利用Lambda表达式可以使代码变得更加简洁。

语法格式:(参数列表) -> { 方法体 };

函数式接口 与 匿名内部类、lambda表达式 (代码)

简单封装一个Person类备用

public class Person {
    private String name;
    private int age;
    public Person() {
    }
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public void show(){
        System.out.println("~(@^_^@)~咻咻咻");
    }
    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + ''' +
                ", age=" + age +
                '}';
    }
}

下面的代码就是函数式接口的相关使用
在使用函数式内部类时,需要确定自己要使用的带不带参数,带几个参数,需不需要返回值。一些常用的函数式接口如下:

接口名称方法声明及功能介绍
Consumervoid accept(T t) ;根据指定的参数执行操作
SupplierT get() ; 得到一个返回值
FunctionR apply(T t) ;根据指定的参数执行操作并返回
Predicateboolean test(T t) ;判断指定的参数是否满足条件

测试代码如下:

public class FunctionalInterface {

    public static void main(String[] args) {

        // 1. 匿名内部类的语法格式: 父类/接口类型 引用变量名 = new 父类/接口类型(){ 方法的重写 }
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                System.out.println("我是既没有参数又没有返回值的方法");
            }
        };
        runnable.run();

        // 2.使用lambda表达式实现函数式接口对象的实现
        //  一个参数可省略参数类型和小括号
        //  只有一条语句时可省略大括号
        //  只有一条语句且是return时,可省略大括号及return
        Runnable runnable1 = () -> System.out.println("lambda表达式实现的既没有参数又没有返回值的方法");
        runnable1.run();

        System.out.println("-----------------------------");

        Consumer consumer = new Consumer() {
            @Override
            public void accept(Object o) {
                System.out.println( o +"有参但没有返回值的方法");
            }
        };
        consumer.accept("友情提示1:");

        Consumer consumer1 = (Object o) -> System.out.println( o +"有参但没有返回值的方法");
        Consumer consumer2 = (o) -> System.out.println( o +"有参但没有返回值的方法");
        Consumer consumer3 = o -> System.out.println( o +"有参但没有返回值的方法");
        consumer1.accept("友情提示2");

        System.out.println("-----------------------------");

        Supplier supplier = new Supplier() {
            @Override
            public Object get() {
                return "我是一个无参有返回值的函数式接口方法";
            }
        };
        System.out.println(supplier.get());

        Supplier supplier1 = () -> {return "我是一个无参有返回值的函数式接口方法";};
        Supplier supplier2 = () ->  "我是一个无参有返回值的函数式接口方法";
        supplier1.get();

        System.out.println("------------------------------");


        Function function = new Function() {
            @Override
            public Object apply(Object o) {
                return o;
            }
        };
        System.out.println(function.apply("Function是一个有参有返回值的函数式接口"));

        Function function1 = o -> o;
        System.out.println(function1.apply("11"));
    }
}

方法的引用

方法引用主要指通过方法的名字来指向一个方法而不需要为方法引用提供方法体,该方法的调用交给函数式接口执行。就是我通过类名或者对象名,直接指向该类或者该对象中的某一个方法。

匿名内部类、lambda和方法引用其实是相通的,从匿名内部类到lambda到方法引用是一个进化的过程,是一个简化的过程,更加是一个从抽象的过程。作用都是实现接口方法,换句话说就是实现接口;只是这个接口只有一个抽象方法。

方法的引用使用一对 :: 通过类或对象指向方法,通常使用方式如下:

  • 对象的非静态方法引用 ObjectName :: MethodName
  • 类的静态方法引用 ClassName ::StaticMethodName
  • 类的非静态方法引用 ClassName :: MethodName
  • 构造器的引用 ClassName :: new
  • 数组的引用 TypeName[] :: new

方法引用是在特定场景下lambda表达式的一种简化表示,可以进一步简化代码的编写使代码更加
紧凑简洁,从而减少冗余代码。

对应代码如下(跟课程练习时写的代码,太长了,慎看…):

public static void main(String[] args) {

        // 1.使用匿名内部类的方式通过函数式接口Runnable中的方法实现对Person中show方法的调用
        Person person = new Person("章法",13);
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                person.show();
            }
        };
        runnable.run(); // ~(@^_^@)~咻咻咻

        System.out.println("--------------------------------------------------");
        // 2.使用lambda表达式的方式通过函数式接口Runnable中的方法实现对Person中show方法的调用
        Runnable runnable1 = () -> person.show();
        runnable1.run();// ~(@^_^@)~咻咻咻

        System.out.println("--------------------------------------------------");
        // 3.使用方法引用的方式实现Person类中show方法的调用
        Runnable runnable2 = person::show;  // 方法引用
        runnable2.run();


        System.out.println("--------------------------------------------------");
        // 4.使用函数内部类的方式实通过函数式接口Consumer中的方法实现Person中setName方法的使用
        Consumer consumer = new Consumer() {
            @Override
            public void accept(String s) {
                person.setName(s);
            }
        };
        consumer.accept("guanyu");
        System.out.println("Person = " + person);

        System.out.println("--------------------------------------------------");
        // 5.使用lambda表达式的方法实现Person类中setName方法的使用
        Consumer consumer1 = s -> person.setName(s);
        consumer1.accept("liubei");
        System.out.println("Person = " + person);

        System.out.println("--------------------------------------------------");
        // 6.使用  方法引用 的方式使用Person类中serName方法的使用
        Consumer consumer2 = person::setName;
        consumer2.accept("zhangfei");
        System.out.println("Person = " + person);


        System.out.println("--------------------------------------------------");
        // 7.使用函数内部类的方式实通过函数式接口Supplier中的方法实现Person中getName方法的使用
        Supplier stringSupplier = new Supplier() {
            @Override
            public String get() {
                return person.getName();
            }
        };
        System.out.println(stringSupplier.get());

        Supplier stringSupplier1 = () -> person.getName();
        System.out.println(stringSupplier1.get());

        Supplier stringSupplier2 = person::getName;
        System.out.println(stringSupplier2.get());


        System.out.println("--------------------------------------------------");
        // 8.(类的静态方法引用)使用匿名内部类的方式通过函数式接口Function中的方法实现Integer类中parseInt方法(将字符串转换为整数)的调用
        Function function = new Function() {
            @Override
            public Integer apply(String s) {
                return Integer.parseInt(s);
            }
        };
        System.out.println(function.apply("12345"));// 12345

        Function function1 = s -> Integer.parseInt(s);
        System.out.println(function1.apply("12345"));// 12345


        Function function2 = Integer::parseInt;
        System.out.println(function2.apply("12345")); // 12345

        System.out.println("--------------------------------------------------");
        // 9.(类的静态方法引用)使用匿名内部类的方式通过函数式接口Comparator中的方法实现Integer类中compare方法的调用
        Comparator comparator = new Comparator() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return Integer.compare(o1,o2);
            }
        };
        System.out.println(comparator.compare(1, 2)); // -1

        Comparator comparator1 = (o1,o2) -> Integer.compare(o1,o2);
        System.out.println(comparator1.compare(1, 2));  // -1

        Comparator comparator2 = Integer::compare;
        System.out.println(comparator2.compare(1, 2));  // -1

        System.out.println("--------------------------------------------------");
        // 10.(类的静态方法引用)使用匿名内部类的方式通过类名来调用非静态方法
        // 其中一个参数作为调用对象来调用方法时,可以使用上述方式  更加抽象
        Comparator comparator3 = new Comparator() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return o1.compareTo(o2);
            }
        };
        System.out.println(comparator3.compare(1, 2));  // -1

        Comparator comparator4 = (o1, o2) -> o1.compareTo(o2);
        System.out.println(comparator4.compare(1, 2));  // -1


        Comparator comparator5 = Integer::compareTo;
        System.out.println(comparator5.compare(1, 2));  // -1

        System.out.println("--------------------------------------------------");
        // 11.(构造器的引用)使用匿名内部类的方式通过Supplier函数式接口采用无参方式创建Person类型的对象并返回
        Supplier supplier = new Supplier() {
            @Override
            public Person get() {
                return new Person();
            }
        };
        System.out.println(supplier.get());   // Person{name='null', age=0}

        Supplier supplier1 = () -> new Person();
        System.out.println(supplier1.get());   // Person{name='null', age=0}

        Supplier supplier2 = Person::new;
        System.out.println(supplier2.get());   // Person{name='null', age=0}

        System.out.println("--------------------------------------------------");
        // 12.(构造器的引用)使用匿名内部类的方式通过BiFunction函数式接口采用有参方式创建Person类型的对象并返回
        BiFunction biFunction = new BiFunction() {
            @Override
            public Person apply(String s, Integer integer) {
                return new Person(s,integer);
            }
        };
        System.out.println(biFunction.apply("zhanfei", 30));  // Person{name='zhanfei', age=30}

        BiFunction biFunction1 = (s,integer)->new Person(s,integer);
        System.out.println(biFunction1.apply("liubei", 40));   // Person{name='liubei', age=40}

        BiFunction biFunction2 = Person::new;
        System.out.println(biFunction2.apply("guanyu", 35));   // Person{name='guanyu', age=35}


        System.out.println("--------------------------------------------------");
        // 12.(数组的引用)使用匿名内部类的方式通过Function函数式接口采用创建指定数量的Person类型的对象数组并返回
        Function function3 = new Function() {
            @Override
            public Person[] apply(Integer integer) {
                return new Person[integer];
            }
        };
        System.out.println(Arrays.toString(function3.apply(3)));   // [null, null, null]

        Function function4 = integer -> new Person[integer];
        System.out.println(Arrays.toString( function4.apply(4)));   // [null, null, null, null]

        Function function5 = Person[]::new;
        System.out.println(Arrays.toString(function5.apply(5)));    // [null, null, null, null, null]
    }
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/489156.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号