java入门~第二十六天 JDK1.8的新特性之Lambda表达式以及方法引用

1. JDK1.8的新特性之Lambda表达式

Lambda 是一个匿名函数,我们可以把 Lambda表达式理解为是一段可以传递的代码(将代码像数据一样进行传递)。可以写出更简洁、更灵活的代码。作为一种更紧凑的代码风格,使Java的语言表达能力得到了提升。

1.01如何书写Lambda的表达式

public interface MyInterface {
    //接口
    public abstract void show();
}
public class Mytest {
    public static void main(String[] args) {
       MyInterface myInterface = new MyInterface() {

            @Override
            public void show() {
                System.out.println("show");
            }
        };
        myInterface.show();//show 记住不能用MyInterface直接调方法
    }
}

其实也可以用Lambda简化匿名内部类

public class Mytest {
    public static void main(String[] args) {
       MyInterface myInterface = () -> System.out.println("show");
       myInterface.show();
    }
}

1.02Lambda的表达式简化方式

public interface MyInterface {
    public int test(String name, int age);
}

形参的数据类型也可以省略不写

public class MyTest {
    public static void main(String[] args) {
        MyInterface myInterface = new MyInterface() {
            @Override
            public int test(String name, int age) {
                System.out.println(name + "==" + age);
                return 100;
            }
        };
        //第一步简写
        MyInterface myInterface2 = (String name, int age) -> {
            System.out.println(name + "==" + age);
            return 100;
        };
        //第二步简写 形参的数据类型也可以省略不写
        MyInterface myInterface3 = (name, age) -> {
            System.out.println(name + "==" + age);
            return 100;
        };

如果你对接口中的抽象方法的具体实现逻辑,只有一行代码,可以省略return关键字和{}

public class MyTest2 {
    public static void main(String[] args) {
        MyInterface myInterface = new MyInterface() {
            @Override
            public int test(String name, int age) {
                return name.hashCode() + age;
            }
        };
        //第一次简写
        MyInterface myInterface2 = (String name, int age) -> {
            return name.hashCode() + age;
        };
        //第二次简写
        MyInterface myInterface3 = (name, age) -> {
            return name.hashCode() + age;
        };
        //第三次简写:如果你对接口中的抽象方法的具体实现逻辑,只有一行代码,可以省略return关键字和{}
        //参数有一个 ()也可以省略
        MyInterface myInterface4 = (name, age) -> name.hashCode() + age;
        // name.hashCode() name的hashcode值  一个数字
        
    }
}

1.03Lambda表达式使用条件

当接口中只有一个抽象方法,才能使用Lambda表达式来简写。
Lambda表达式zhi只支持函数式接口:接口中只有一个抽象方法
@FunctionalInterface 这个注解可以检测这个接口是不是个函数式接口

1.04Lambda作为参数传递

public class Mytest1 {
    public static void main(String[] args) {
        Integer[] arr = {20, 30, 4, 2};
        //Lambda作为参数传递
        Arrays.sort(arr, (a, b) -> a - b);
        System.out.println(Arrays.toString(arr));//[2, 4, 20, 30]
    }
}

1.05Lambda表达式中其他函数式接口

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

        new Consumer<Integer>() {
            @Override
            public void accept(Integer integer) {
				 System.out.println("哈哈");
            }
        };
    }
}

即:

public class Mytest1 {
    public static void main(String[] args) {
        Consumer<Integer> consumer= integer -> System.out.println("哈哈");
    }
}

总结:

Lambda 表达式在Java 语言中引入了一个新的语法元素和操作符。这个操作符为 “ ->” , 该操作符被称为 Lambda 操作符或箭头操作符。它将 Lambda 分为两个部分:

左侧: 指定了 Lambda 表达式需要的所有参数
右侧: 指定了 Lambda 体,即 Lambda 表达式要执行的功能。

补充:Java中提供的4大核心函数式接口

函数式接口参数类型返回类型用途
**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);

其他函数式接口

返回类型参数类型用途函数式接口
RT U对类型为 T, U 参数应用 操作, 返回 R 类型的结 果。 包含方法为 R apply(T t, U u);BiFunction<T,U,R>
TT对类型为T的对象进行一 元运算, 并返回T类型的 结果。 包含方法为 T apply(T t);UnaryOperator****(Function的子接口)
TT T对类型为T的对象进行二 元运算, 并返回T类型的 结果。 包含方法为 T apply(T t1, T t2);BinaryOperator(BiFunction的子接口)
voidT U对类型为T, U 参数应用 操作。 包含方法为 void accept(T t, U u)BiConsumer<T,U>
int long doubleT分 别 计 算 int 、 long 、 double、 值的函数**ToIntFunction****ToLongFunction**ToDoubleFunction
Rint long double参数分别为int、 long、 double 类型的函数**IntFunction****LongFunction**DoubleFunction

2.方法引用

我们先来看一下什么是方法引用:方法引用其实是Lambda表达式的另一种写法,当要传递给Lambda体的操作,已经有实现的方法了,可以使用方法引用。

注意:实现抽象方法的参数列表,必须与方法引用方法的参数列表保持一致!

方法引用:使用操作符 “ ::” 将方法名和对象或类的名字分隔开来。

如下三种主要使用情况:

​ 对象::实例方法
​ 类::静态方法
​ 类::实例方法

2.01类::静态方法

方法引用:

你要看你对接口中这个抽象方法的重写逻辑
Consumer接口中这个抽象方法 accept(String s) 返回值是void 参数只有一个参数
我们对这个accept(String s)这个方法的重写逻辑 System.out.println(s);
对象.println(s) 这个println(s)方法的返回值是void 方法的参数也是一个,正好跟我们重写的accept(String s)
的返回值类型和参数列表能对应上,那么我就可以使用方法引用,来简写。

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

        BinaryOperator<Double> binaryOperator = new BinaryOperator<Double>() {
            @Override
            public Double apply(Double aDouble, Double aDouble2) {
                double max = Math.max(aDouble, aDouble2);
                return max;
                // public static double max(double a, double b) {静态方法}
            }
        };

        BinaryOperator<Double> binaryOperator2 = (a, b) -> Math.max(a, b);
        //方法引用
        BinaryOperator<Double> binaryOperator3 = Math::max;

        System.out.println("===================================");
       
    }
}

2.02对象::实例方法

public class MyTest2 {
    public static void main(String[] args) {
        // BiConsumer
        // void accept (T t, U u);

        Supplier<Double> supplier = new Supplier<Double>() {
            @Override
            public Double get() {
                Random random = new Random();
                double v = random.nextDouble();
                return v;
            }
        };

        Supplier<Double> supplier2 = () -> new Random().nextDouble();

        Supplier<Double> supplier3 = new Random()::nextDouble;
    }
}

2.03 类::实例方法

public class MyTest {
    public static void main(String[] args) {
        Consumer<String> consumer = new Consumer<String>() {
            @Override
            public void accept(String s) {

                PrintStream out = System.out;
                out.println(s);
            }
        };

        //简化
        Consumer<String> consumer2 = s -> System.out.println(s);
        // public void println(String x) {
        //synchronized (this) {
        //    print(x);
        //   newLine();
        // }
    }

        //继续简化
        Consumer<String> consumer3 = System.out::println;
    }
}

传入的两个参数,一个作为了调用者,一个作为了传入者,也可以使用方法引用进行简写。

public class MyTest3 {
    public static void main(String[] args) {
        Comparator<String> comparator = new Comparator<String>() {
            @Override
            public int compare(String s1, String s2) {
                //传入的两个参数,一个作为了调用者,一个作为了传入者,也可以使用方法引用进行简写。
                int i = s1.compareTo(s2);
                return i;
            }
        };

        Comparator<String> comparator2 = (s1, s2) -> s1.compareTo(s2);

        Comparator<String> comparator3 = String::compareTo;

    }
}

3.构造器引用

public class Student {
    public Student() {
    } ///空参构造

    public Student(String name, int age) {
    }
}
public class MyTest {
    public static void main(String[] args) {
        Supplier<Student> supplier = new Supplier<Student>() {
            @Override
            public Student get() {
                return new Student();
            }
        };

        Supplier<Student> supplier2 = () -> new Student();

        //构造引用
        Supplier<Student> supplier3 = Student::new;
        System.out.println("============================");
        BiFunction<String, Integer, Student> biFunction = new BiFunction<String, Integer, Student>() {
            @Override
            public Student apply(String s, Integer integer) {
                return new Student(s, integer);
            }
        };

        BiFunction<String, Integer, Student> biFunction2 = Student::new;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值