美文网首页
jdk8新特性-Lambda表达式及函数式接口

jdk8新特性-Lambda表达式及函数式接口

作者: 攻城老狮 | 来源:发表于2021-08-26 18:24 被阅读0次
  1. 在多线程方面,Lambda表达式的使用
  • 不使用Lambda表达式的情况下,开启多线程的方式
/*
测试:开启多线程,打印数据
结论:不使用函数式编程带来冗余
 */
public class Demo01Runnable {
    public static void main(String[] args) {
        //使用Runnable的实现类,完成方法调用
        RunnableImpl r = new RunnableImpl();
        Thread t = new Thread(r);
        t.start();
        //使用匿名内部类简化编码
        Runnable r2 = new Runnable() {
            @Override
            public void run() {
                System.out.println("匿名内部类的方式开启多线程...run...");
            }
        };
        new Thread(r2).start();
        //进一步简化
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("匿名内部类的方式开启多线程2...run...");
            }
        }).start();
    }
}
  • 使用Lambda表达式实现多线程方法调用
/*
    Lambda表达式的标准格式:
        三部分组成:一些参数,一个箭头,一段代码
        格式:
            (参数列表)->{一些重写方法的代码}
 */
/*
    Lambda表达式是可推导,可省略的
    省略的内容:
        1.(参数列表):括号中的参数列表的数据类型可以省略
        2.(参数列表):若括号中参数只有一个,那么类型和()都可以省略
        3.{一些代码}:若{}中的代码只有一行,无论是否有返回值,都可以省略 {},return,分号
            注意:必须一起省略
 */
public class Demo02Lambda {
    public static void main(String[] args) {
        //使用匿名内部类的方式实现多线程
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("匿名内部类...run...");
            }
        }).start();
        //使用Lambda表达式实现多线程
        new Thread(()->{
            System.out.println("Lambda表达式...run...");
        }).start();
        //省略的Lambda表达式
        new Thread(()->System.out.println("Lambda表达式...run...")).start();
    }
}
  1. 自定义接口,并使用Lambda表达式的方式调用
  • 自定义接口
public interface Cook {
    public abstract void makeFood();
}
  • 使用Lambda表达式调用自定义接口
/*
    练习:给定一个Cook接口,内含唯一抽象方法makeFood,无参无返回值。
    使用Lambda的格式调用invokeCook方法,打印数据
 */
public class Demo01Cook {
    public static void main(String[] args) {
        //匿名内部类的方式
        invokeCook(new Cook() {
            @Override
            public void makeFood() {
                System.out.println("makeFood1...");
            }
        });
        //Lambda表达式
        invokeCook(()->{
            System.out.println("makeFood2...");
        });
        //省略的Lambda表达式
        invokeCook(()->System.out.println("makeFood3..."));
    }

    public static void invokeCook(Cook cook){
        cook.makeFood();
    }
}
  1. 实现使用Lambda表达式,对对象中某个属性进行排序的功能
  • 对象JavaBean
public class Person {
    private String name;
    private Integer age;

    public Person() {
    }

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

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

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
  • 使用Lambda表达式的方式对JavaBean进行排序
import java.util.Arrays;

/*
    Lambda表达式有参数有返回值练习:使用数组存储多个Person对象,
    对数组中的Person对象按照age升序(前-后)排序
 */
public class Demo01Arrays {
    public static void main(String[] args) {
        Person[] arr = {
                new Person("yorick",23),
                new Person("tom",12),
                new Person("jerry",16)
        };
        //使用匿名内部类的方式
       /* Arrays.sort(arr, new Comparator<Person>() {
            @Override
            public int compare(Person o1, Person o2) {
                return o1.getAge()-o2.getAge();
            }
        });*/
        //使用Lambda表达式
       /* Arrays.sort(arr,(Person o1,Person o2)->{
            return o1.getAge()-o2.getAge();
        });*/
        //省略的Lambda表达式
        Arrays.sort(arr,(o1,o2)->o1.getAge()-o2.getAge());
        for (Person person : arr) {
            System.out.println(person);
        }
    }
}
  1. 自定义接口,使用Lambda表达式调用,有参数的练习
  • 自定义接口
public interface Calculator {
    public abstract Integer calc(int a,int b);
}
  • 使用Lambda表达式,调用自定义接口
/*
    Lambda有参数有返回值练习:给定一个Calculator接口,内含抽象方法calc计算两数之和,
    使用Lambda表达式调用invokeCalc方法
 */
public class Demo01Calculator {
    public static void main(String[] args) {
        //使用匿名内部类
        invokeCalc(10, 20, new Calculator() {
            @Override
            public Integer calc(int a, int b) {
                return a+b;
            }
        });
        //使用Lambda表达式
        invokeCalc(120,130,(int a,int b)->{
            return a+b;
        });
        //简化的Lambda表达式
        invokeCalc(220,230,(a,b)->a+b);
    }

    public static void invokeCalc(int a,int b,Calculator calculator){
        int result = calculator.calc(a,b);
        System.out.println(result);
    }
}

常用函数式接口

  1. Supplier接口
  • Supplier接口的简单使用
/*
    Supplier<T>接口仅包含一个无参方法:T get() 用于获取一个泛型参数指定类型的对象数据。
    用处:
        该接口称为生产型接口,指定接口的泛型,get方法就会生成什么类型的数据
 */
public class Demo01Supplier {
    public static void main(String[] args) {
        String result = getString(()->"你好");
        System.out.println(result);
    }

    public static String getString(Supplier<String> supplier){
        return supplier.get();
    }
}
  • 使用Supplier接口的案例
import java.util.function.Supplier;

/*
    练习:使用Supplier接口求数组元素的最大值
 */
public class Demo02SupplierGetMax {
    public static void main(String[] args) {
        //定义一组数据
        Integer[] arr = {10,23,-10,0,66};
        //调用getMax方法,方法的参数Supplier是一个函数式接口
        Integer result = getMax(()->{
            int max = arr[0];
            for (Integer i : arr) {
                if(i>max){
                    max = i;
                }
            }
            return max;
        });
        System.out.println(result);
    }

    public static Integer getMax(Supplier<Integer> supplier){
        return supplier.get();
    }
}
  1. Consumer接口
  • Consumer接口简单使用
import java.util.function.Consumer;

/*
    Consumer<T>接口与Supplier接口相反,包含抽象方法 void accept(T t),用于消费一个指定泛型的数据
    用途:
        Consumer是一个消费型接口,泛型是什么类型就可以通过accept方法消费什么类型的数据,
        如何消费可以自己在Lambda表达式中定义
 */
public class Demo01Consumer {
    public static void main(String[] args) {
        method("yorick",(String name)->{
            System.out.println(name);
            //反转字符串
            String reName = new StringBuffer(name).reverse().toString();
            System.out.println(reName);
        });
    }

    public static void method(String name,Consumer<String> consumer){
        consumer.accept(name);
    }
}
  • Consumer的andThen默认方法使用
import java.util.function.Consumer;

/*
    Consumer的默认方法andThen
    作用:需要两个Consumer接口,把两个Consumer接口组合到一起,再对数据进行消费
       若con1连接con2,则con1先消费数据,con2再消费数据
 */
public class Demo02andThen {
    public static void main(String[] args) {
        method("Yorick",
                (name)->{
                    System.out.println(name.toUpperCase());
                },
                (name)->{
                    System.out.println(name.toLowerCase());
                });
    }

    public static void method(String name, Consumer<String> consumer1,Consumer<String> consumer2){
        //不使用andThen方法
        /*consumer1.accept(name);
        consumer2.accept(name);*/
        //使用andThen方法
        //consumer1.andThen(consumer2).accept(name);
        //使用andThen方法 先消费consumer2
        consumer2.andThen(consumer1).accept(name);
    }
}
  • 使用Consumer接口的案例
import java.util.function.Consumer;

/*
    练习:
        使用Consumer接口,将字符串数组中多条信息按照"姓名:xx,性别:xx"的格式打印
 */
public class Demo03StringSplit {
    public static void main(String[] args) {
        //定义一个字符串数组
        String[] arr = {"yorick,boy","tom,boy","lucy,girl"};
        //Lambda表达式实现功能
        method(arr,
                (message)->{
                    String name = message.split(",")[0];
                    System.out.print("姓名:"+name);
                },
                (message)->{
                    String gender = message.split(",")[1];
                    System.out.println(",性别:"+gender);
                });
    }

    public static void method(String[] arr, Consumer<String> consumer1,Consumer<String> consumer2){
        for (String message : arr) {
            consumer1.andThen(consumer2).accept(message);
        }
    }
}
  1. Predicate接口
  • Predicate接口简单使用
import java.util.function.Predicate;

/*
    Predicate<T>接口,包含一个抽象方法 boolean test(T t) 用来对指定数据类型数据进行判断的方法
       作用:对某种数据类型的数据进行判断,结果返回一个boolean值
            结果:符合条件,true;不符合条件,false
 */
public class Demo01Predicate {
    public static void main(String[] args) {
        String str = "yorick";
        /*Boolean result = checkString(str,(String s)->{
            return s.length()>5;
        });*/
        //简化
        Boolean result = checkString(str,s->s.length()>5);
        System.out.println(result);
    }

    public static Boolean checkString(String str, Predicate<String> predicate){
        return predicate.test(str);
    }
}
  • Predicate接口的默认方法and的使用
import java.util.function.Predicate;

/*
    案例:
        使用and连接两个Predicate
        满足:1.长度大于5
             2.包含字母y
 */
public class Demo02PredicateAnd {
    public static void main(String[] args) {
        String str = "yorick";
        Boolean result = checkString(str,
                (String s)->{
                    //长度大于5
                    return s.length()>5;
                },(String s)->{
                    //包含字母y
                    return s.contains("y");
                });
        System.out.println(result);
    }

    public static Boolean checkString(String str, Predicate<String> predicate1,Predicate<String> predicate2){
        return predicate1.and(predicate2).test(str);//等价于 return predicate1.test(str) && predicate2.test(str);
    }
}
  • 使用Predicate接口的案例
import java.util.ArrayList;
import java.util.function.Predicate;

/*
    练习:集合信息筛选,通过Predicate接口实现对字符串数组进行筛选的功能,
    需要同时满足的条件:
        1.必须为male
        2.姓名字母5个以上
 */
public class Demo03PracticeTest {
    public static void main(String[] args) {
        //定义一个字符串数组
        String[] str = {"yorick,male","tom,male","torasa,female","jackson,male"};
        //调用方法进行筛选
        ArrayList<String> list = filter(str, (String s) -> {
            return s.split(",")[0].length() > 5;
        }, (String s) -> {
            return s.split(",")[1].equals("male");
        });
        //遍历结果
        for (String s : list) {
            System.out.println(s);
        }
    }
    public static ArrayList<String> filter(String[] str, Predicate<String> pre1,Predicate<String> pre2){
        ArrayList<String> result = new ArrayList<>();
        for (String s : str) {
            boolean flag = pre1.and(pre2).test(s);
            if(flag == true){
                result.add(s);
            }
        }
        return result;
    }
}
  1. Function接口
  • Function接口的简单使用
import java.util.function.Function;

/*
    Function<T,R>接口用来根据一个类型的数据得到另一个类型的数据。
    前者称为前置条件,后者称为后置条件
    Function接口的主要抽象方法为:R apply(T t) 根据类型T的参数获取类型R的结果
 */
//将String类型转换为Integer类型
public class Demo01Function {
    public static void main(String[] args) {
        StringToInteger("233",s->Integer.parseInt(s));
    }
    public static void StringToInteger(String s, Function<String,Integer> fun){
        Integer result = fun.apply(s);
        System.out.println(result);
    }
}
  • Function接口的默认方法andThen使用
import java.util.function.Function;

/*
    Function接口的默认方法andThen用来进行组合操作

    需求:把String类型的"233"转换为Integer类型并结果+10,
    把增加之后的Integer类型的数据再转换为String类型
 */
public class Demo02AndThen {
    public static void main(String[] args) {
        /*change("233",(String s)->{
            return Integer.parseInt(s)+10;
        },(Integer i)->{
            return i+"";
        });*/
        //简化Lambda表达式
        change("233",s->Integer.parseInt(s)+10,i->i+"");
    }

    public static void change(String s, Function<String,Integer> fun1,Function<Integer,String> fun2){
        String result = fun1.andThen(fun2).apply(s);
        System.out.println(result);
    }
}

相关文章

  • 《Java 8实战》学习总结

    Java 8新特性概览 Lambda表达式 流 默认方法 Lambda表达式 Lambda和函数式接口Java 8...

  • lambda表达式

    概要: 函数式编程特性 lambda表达式语法及应用场景 Java 8自带函数式接口详解 一、函数式编程特性 1....

  • Lambda表达式详解

    什么是Lambda表达式 Lambda表达式是Java 8的新特性,是函数式接口的实例。使用Lambda表达式可以...

  • JDK8stream将list转Map对象报错java.lang

    ​ JDK8有很多新特性,比如lambda表达式,函数式编程以及stream流的使用,这几个新特性,使用过之后就爱...

  • JDK8新特性 - 函数式编程

    一、JDK8之自定义函数式编程 1.使用Lambda表达式,自定义lambda接口编程 定义⼀个函数式接口 需要标...

  • Chapter 14 . JDK8新特性

    阅读原文 Chapter 14 . JDK8新特性 14.1 Lambda 表达式 Lambda 是一个匿名函数,...

  • Java 接口知识点

    接口的特性 函数式接口 抽象类和接口区别 Lambda表达式 java常用接口

  • Lambda表达式

    Lambda表达式是Java8的一个新特性,是函数式接口的一种体现。所谓函数式接口(functional inte...

  • Lambda与函数式接口

    JDK8 于2014年发布至今,已有6个年头。其中几个重要的特性,lambda表达式,函数式接口,方法引用,默认方...

  • JDK新特性(四)——函数式接口

    前言 函数式接口是JDK1.8推出的新特性之一,可以说函数式接口给Lambda表达式这种函数提供了简便的使用环境,...

网友评论

      本文标题:jdk8新特性-Lambda表达式及函数式接口

      本文链接:https://www.haomeiwen.com/subject/ievuiltx.html