Java8新特性-Lambda表达式入门

Java8新特性

主要内容

  • Lamdba表达式
  • 函数式接口
  • 方法引用和构造器引用
  • Stream API
  • 接口中的默认方法与静态方法
  • 新时间日期API
  • 其他新特性

java8新特性介绍

  • 速度更快(HashMap、元空间)
  • 代码更少(Lambda表达式)
  • 强大的Stream API(将java变成sql)
  • 便于并行()
  • 最大化减少空指针异常

Lamdba和Stream 为核心

一、Lambda表达式

为什么使用Lambda表达式

Lamdba是一个匿名函数,我们可以将Lambda表达式理解为是一段可以传递的代码(将代码像数据一样进行传递)。

Lambda表达式基础语法

java8引入新的操作符 “->” 该操作符称为箭头操作或Lambda操作符

箭头操作符将Lambda 拆分为两部分
左侧:Lambda 表达式的参数列表
右侧:Lambda 表达式所执行的功能,即Lambda体

Lambda六种基本格式

  1. 无参数、无返回值

    ()-> System.out.println(“Hello,Lambda”)

      @Test
        public void test1(){
            //JDK 1.7之前必须加final; 1.8后默认为final
            int num=0;
    		Runnable runnable=new Runnable() {
                @Override
                public void run() {
                    System.out.println("hello"+num);
                }
            };
            runnable.run();
    
            System.out.println("================");
    		/**
    		()-> System.out.println("Hello,Lambda")
    		*/
            Runnable runnable1=()-> System.out.println("hello"+num);
            runnable1.run();
        }
    
  2. 一个参数、无返回值

    (s)->System.out.println(s)

     @Test
        public void test2(){
            Consumer<String> consumer=new Consumer<String>() {
                @Override
                public void accept(String s) {
                    System.out.println("匿名内部类"+s);
                }
            };
    		
            Consumer<String> consumer1=(s)-> System.out.println("Lambda表达式 "+s);
            consumer1.accept("这是参数");
        }
    
  3. 一个参数、无返回值;小括号可以省略

    s->System.out.println(s)

     @Test
        public void test2(){
            Consumer<String> consumer=new Consumer<String>() {
                @Override
                public void accept(String s) {
                    System.out.println("匿名内部类"+s);
                }
            };
    		
            Consumer<String> consumer1=(s)-> System.out.println("Lambda表达式 "+s);
            consumer1.accept("这是参数");
    		 /**
             * 当参数为一个时,小括号可以省略
             */
            Consumer<String> consumer2=s-> System.out.println("Lambda表达式 "+s);
            consumer2.accept("小括号没了");
        }
    
  4. 两个以上的参数、有返回值、并且Lambda 体中有多条语句

    Comparator comparator=(x,y)->{
    System.out.println(“函数式接口”);
    return Integer.compare(x,y);
    };

     @Test
        public void test3(){
            Comparator<Integer> comparator=(x,y)->{
                System.out.println("函数式接口");
                return Integer.compare(x,y);
            };
        }
    
    
  5. 若Lambda 体只有一条语句,return 和 大括号都可以省略不写

    Comparator comparator1=(x,y)->Integer.compare(x,y);

 @Test
    public void test4(){
        Comparator<Integer> comparator=(x,y)->Integer.compare(x,y);
    }

6.Lambda表达式参数的数据类型可以省略不写,因为JVM可以通过上下文推断出类型即“类型推断”

@Test
    public void test4(){
        /**
         * 数据类型可以省略
         */
        Comparator<Integer> comparator=(Integer x,Integer y)->Integer.compare(x,y);
    }

小结:左右遇一括号省,左侧推断类型省。

Lambda表达式需要函数式接口支持

函数式接口:接口中只有一个抽象方法的接口,可以使用@FunctionalInterface修饰,作用类似@Overweite。

简单的使用

自定义一个通用算法接口,求一个数的平方

@FunctionalInterface
public interface MyFun<T>{
    public T getValue(T num);
}

package org.lfh.java8.mylambdaplus;
public class MyFunDemo {
    public static void main(String[] args) {
        /**
         * 求一个数的平方
         */
        Integer operation = operation(100, new MyFun<Integer>() {
            @Override
            public Integer getValue(Integer num) {
                return num * num;
            }
        });
        System.out.println("operation = " + operation);
        /**
         * Lambda表达式
         */
        Integer operation1 = operation(100, x -> x * x);
        System.out.println("Lambda表达式" + operation1);

    }
    public static Integer operation(Integer num,MyFun<Integer> myFun){
        return myFun.getValue(num);
    }
}

Lambda练习

  1. 调用Collections.sort()方法,通过定制排序比较俩个Employee(先按年龄比,年龄相同按姓名比),使用Lambda作为参数传递

    package org.lfh.java8.lambdademo;
    
    import java.util.Objects;
    
    /**
     * @author lifh
     * @creat 2020/10/25/20:59
     */
    public class Employee {
        /**
         * 年龄
         */
        private Integer age;
        /**
         * 姓名
         */
        private String name;
    
        public Employee() {
        }
    
        public Employee(Integer age, String name) {
            this.age = age;
            this.name = name;
        }
    
        public Integer getAge() {
            return age;
        }
    
        public void setAge(Integer age) {
            this.age = age;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        @Override
        public String toString() {
            return "Employee{" +
                    "age=" + age +
                    ", name='" + name + '\'' +
                    '}';
        }
    
        @Override
        public boolean equals(Object o) {
            if (this == o) {
                return true;
            }
            if (o == null || getClass() != o.getClass()) {
                return false;
            }
            Employee employee = (Employee) o;
            return Objects.equals(age, employee.age) &&
                    Objects.equals(name, employee.name);
        }
    
        @Override
        public int hashCode() {
            return Objects.hash(age, name);
        }
    }
    
    
    package org.lfh.java8.lambdademo;
    
    /**
     * @author lifh
     * @creat 2020/10/25/21:00
     */
    
    import java.util.ArrayList;
    import java.util.Collections;
    
    /**
     * 调用Collections.sort()方法,
     * 通过定制排序比较俩个Employee(先按年龄比,年龄相同按姓名比),
     * 使用Lambda作为参数传递
     *
     * @author lfh
     */
    public class Demo {
        public static void main(String[] args) {
            Employee employee1 = new Employee(18, "李四");
            Employee employee = new Employee(18, "张三");
            Employee employee2 = new Employee(16, "张三");
    
    
            ArrayList<Employee> arrayList = new ArrayList<>();
            arrayList.add(employee);
            arrayList.add(employee1);
            arrayList.add(employee2);
    
            Collections.sort(arrayList, (e1, e2) -> {
                if (e1.getAge() - e2.getAge() == 0) {
                    return e1.getName().compareTo(e2.getName());
                } else {
                    return Integer.compare(e1.getAge(), e2.getAge());
                }
            });
            System.out.println("arrayList = " + arrayList);
        }
    }
    
    
  • 声明函数式接口,接口中声明抽象方法,Public String getValue(Sting str);

    package org.lfh.java8.lambdademo;
    
    /**
     * @author lifh
     * @creat 2020/10/25/21:14
     */
    @FunctionalInterface
    public interface MyFun {
        /**
         * @param str
         * @return
         */
        public String getValue(String str);
    }
    
    
  • 声明类TestLambda,类中编写方法使用接口作为参数,将一个字符串转化为大写,并作为方法的返回值

    package org.lfh.java8.lambdademo;
    
    /**
     * @author lifh
     * @creat 2020/10/25/21:16
     */
    public class TestLambda {
        public static void main(String[] args) {
            String abc = getBigValue("abc", x -> x.toUpperCase());
            System.out.println("abc = " + abc);
        }
        /**
         * 接口作为参数,将一个字符串转化为大写,并作为方法的返回值
         */
        public static String getBigValue(String str,MyFun myFun){
            return myFun.getValue(str);
        }
    }
    
  • 再将一个字符串的第二个和第四个索引进行截取字符串

    /**
         * 将一个字符串的第二个和第四个索引进行截取字符串
         */
        String subStr = getBigValue("我是吴彦祖", x -> x.substring(2, 5));
        System.out.println("截取后 = " + subStr);
  • 声明一个带两个泛型参数的函数式接口,泛型类型为<T,R>,T为参数,R为返回值。

    package org.lfh.java8.lambdademo;
    
    /**
     * @author lifh
     * @creat 2020/10/25/21:27
     */
    public interface MyFunction2<T,R> {
        /**
         * 获取值
         * @param t1
         * @param t2
         * @return
         */
        public R getValue(T t1,T t2);
    }
    
    
  • 接口声明对应的抽象方法

  • 在TestLambda类中声明方法,使用接口作为参数,计算两个long类参数的和。

  • package org.lfh.java8.lambdademo;
    
    /**
     * @author lifh
     * @creat 2020/10/25/21:16
     */
    public class TestLambda {
        public static void main(String[] args) {
            /**
             * 接口作为参数,将一个字符串转化为大写,并作为方法的返回值
             */
            String abc = getBigValue("abc", x -> x.toUpperCase());
            System.out.println("abc = " + abc);
    
            /**
             * 将一个字符串的第二个和第四个索引进行截取字符串
             */
            String subStr = getBigValue("我是吴彦祖", x -> x.substring(2, 5));
            System.out.println("截取后 = " + subStr);
    
            /**
             * 计算两个long类参数的和
             */
            longT(100L,200L,(e1,e2)->e1+e2);
        }
    
        public static String getBigValue(String str, MyFun myFun) {
            return myFun.getValue(str);
        }
    
        public static void longT(Long l1,Long l2, MyFunction2<Long,Long> myFunction2) {
            Long value = myFunction2.getValue(l1, l2);
            System.out.println("value = " + value);
        }
    }
    
    
  • 再计算两个long型参数的乘积

      /**
             * 两个long型参数的乘积
             */
            longT(100L,200L,(e1,e2)->e1*e2);
    

Java内置四大核心接口

函数式接口参数类型返回类型用途
Consumer 消费性接口Tvoid对类型为T的对象应用操作,包含方法:void accept(T t)
Supplier 供给型接口T返回类型为T的对象,包含方法 T get()
Function<T,R> 函数新接口TR对类型为T的对象应用操作,并返回结果。结果是R的类型对象,包含方法: R apply(T t);
Predicate 断定型接口Tboolean确定T类型的对象是否满足某种约束,并返回boolean值。包含方法 boolean test(T t);
  • 消费型接口

    package org.lfh.java8.lambdafourkey;
    
    import java.util.function.Consumer;
    
    /**
     * @author lifh
     * @creat 2020/10/25/22:54
     */
    public class FourKey {
        public static void main(String[] args) {
            /**
             * Consumer消费性接口
             */
            consumerTest(1000,x-> System.out.println("每次❀"+x+"买吃的"));
    
        }
    
        public static void consumerTest(Integer money, Consumer<Integer> consumer){
             consumer.accept(money);
        }
    }
    
    
  • 供给型接口

    package org.lfh.java8.lambdafourkey;
    
    import java.util.ArrayList;
    import java.util.List;
    import java.util.function.Consumer;
    import java.util.function.Supplier;
    
    /**
     * @author lifh
     * @creat 2020/10/25/22:54
     */
    public class FourKey {
        public static void main(String[] args) {
            /**
             * Supplier供给型接口
             * 产生指定个数整数,并放入集合
             */
            List<Integer> integers = supplierTest(10, () -> (int) (Math.random() * 100));
            System.out.println("integers = " + integers);
    
        }
    
        public static List<Integer> supplierTest(int num,Supplier<Integer> supplier){
            ArrayList<Integer> arrayLis=new ArrayList<>();
            for (int i=0;i<=num;i++){
                Integer number = supplier.get();
                arrayLis.add(number);
            }
            return arrayLis;
        }
    }
    
    
  • 函数型接口

    package org.lfh.java8.lambdafourkey;
    
    import java.util.ArrayList;
    import java.util.List;
    import java.util.function.Consumer;
    import java.util.function.Function;
    import java.util.function.Supplier;
    
    /**
     * @author lifh
     * @creat 2020/10/25/22:54
     */
    public class FourKey {
        public static void main(String[] args) {
            /**
             * 函数式接口
             * 处理字符串
             */
            String str = functionTest("lfh", x -> x.toUpperCase());
            System.out.println("lfh = " + str);
    
        }
    
        public static String functionTest(String str, Function<String,String> function){
            String apply = function.apply(str);
            return apply;
        }
    }
    
    
  • 断定行接口

    package org.lfh.java8.lambdafourkey;
    
    import java.util.ArrayList;
    import java.util.List;
    import java.util.function.Consumer;
    import java.util.function.Function;
    import java.util.function.Predicate;
    import java.util.function.Supplier;
    
    /**
     * @author lifh
     * @creat 2020/10/25/22:54
     */
    public class FourKey {
        public static void main(String[] args) {
            /**
             * 断定型接口
             * 判断一个int类型的数是否大于1024
             */
            Boolean aBoolean = predicateTest(100, x -> x > 1024);
            System.out.println("aBoolean = " + aBoolean);
    
        }
    
        public static Boolean predicateTest(int number, Predicate<Integer> predicate){
            boolean test = predicate.test(number);
            return test;
        }
    }
    
    
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值