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**消费型接口 | T | void | 对类型为T的对象应用操 作,包含方法: void accept(T t) |
**Supplier**供给型接口 | 无 | T | 返回类型为T的对象,包 含方法: T get(); |
Function<T, R> 函数型接口 | T | R | 对类型为T的对象应用操 作,并返回结果。结果 是R类型的对象。包含方 法: R apply(T t); |
Predicate 断言型接口 | T | boolean | 确定类型为T的对象是否 满足某约束,并返回 boolean 值。包含方法 boolean test(T t); |
其他函数式接口
返回类型 | 参数类型 | 用途 | 函数式接口 |
---|---|---|---|
R | T U | 对类型为 T, U 参数应用 操作, 返回 R 类型的结 果。 包含方法为 R apply(T t, U u); | BiFunction<T,U,R> |
T | T | 对类型为T的对象进行一 元运算, 并返回T类型的 结果。 包含方法为 T apply(T t); | UnaryOperator****(Function的子接口) |
T | T T | 对类型为T的对象进行二 元运算, 并返回T类型的 结果。 包含方法为 T apply(T t1, T t2); | BinaryOperator(BiFunction的子接口) |
void | T U | 对类型为T, U 参数应用 操作。 包含方法为 void accept(T t, U u) | BiConsumer<T,U> |
int long double | T | 分 别 计 算 int 、 long 、 double、 值的函数 | **ToIntFunction****ToLongFunction**ToDoubleFunction |
R | int 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;