Lambad表达式
1.0 Lambda使用的条件
方法的参数是接口,就可以考虑使用Lambda表达式来代替匿名内部类,但不是所有情况都可以是用Lambda表达式。 使用前提条件: 1、方法的参数或局部变量类型必须为接口才能使用; 2、接口中有且仅有一个抽象方法(函数式接口); 补充说明:Lambda表达式的类不可以直接反编译; 工作原理:Lambda表达式会在类里面生成私有的静态方法,Lambda表达式中的方法会放到新增的方法中。 可以使用javap,对字节码进行反汇编,查看字节码指令。 javap -c -p 文件名.class 其实Lambda在运行时会生成一个内部类 可采用命令保存运行时生成的内部类:java -Djdk.internal.lambda.dumpProxyClasses 运行的包名.类名
1.1、体验
@Test
public void hao1() {
// 传统写法-使用匿名内部类
// 1、定义没有名字的类
// 2、实现Runnable接口
// 3、创建类对象
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("线程执行喽!");
}
}).start();
// Lambda表达式
new Thread(() -> {
System.out.println("Lambda线程走起...");
}).start();
}
1.2、排序应用Lambda
class Person {
private String name;
private int age;
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;
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
}
@Test
public void hao2() {
List<Person> list = new ArrayList<Person>();
list.add(new Person("刘德华", 40));
list.add(new Person("张学友", 58));
list.add(new Person("刘三", 30));
list.add(new Person("风清扬", 60));
// Collections.sort(list, new Comparator<Person>() {
// @Override
// public int compare(Person o1, Person o2) {
// return o1.age-o2.age;
// }
// });
//
// list.forEach(s->{
// System.out.println(s);
// });
Collections.sort(list, (o1, o2) -> {
return o1.age - o2.age;
});
list.forEach(System.out::println);
}
1.3、体会前提条件
@SpringBootTest
public class LambdaTest2 {
@Test
public void hao1() {
LambdaTest2.bird(()->{
System.out.println("吃吧");
});
}
@Test
public void hao2() {
Flyable f=()->{
System.out.println("局部方法");
};
f.eat();
}
public static void bird(Flyable f) {
f.eat();
}
interface Flyable{
abstract void eat();
}
}
1.4、函数式接口
@FunctionalInterface
public interface Operator {
public void test();
}
2.1、常用的函数式接口
2.1.1、供给型接口-Supplier
@FunctionalInterface
public interface Supplier<T>{
T get();
}
2.1.2、消费型接口-Consumer
@FunctionalInterface
public interface Consumer<T>{
void accept(T t);
}
2.1.3、函数式接口-Function
@FunctionalInterface
public interface Function<T,R>{
R apply(T t);
}
2.1.4、函数式接口-Predicate
@FunctionalInterface
public interface Predicate<T>{
boolean test(T t);
}
3.1、常用的函数式接口-应用
3.1.1、供给型接口-Supplier
@SpringBootTest
public class SupplierTest {
@Test
public void hao1() {
SupplierTest.printMax(()->{
Integer[] arr= {1,100,30,50};
Arrays.sort(arr);
return arr[arr.length-1];
});
}
public static void printMax(Supplier<Integer> s) {
Integer max = s.get();
System.out.println("max:"+max);
}
}
3.1.2、消费型接口-Consumer
@SpringBootTest
public class ConsumerTest {
@Test
public void hao1() {
ConsumerTest.test(s->{
String lowerCase = s.toLowerCase();
System.out.println(lowerCase);
});
}
public static void test(Consumer<String> s) {
s.accept("Hello world");
}
}
…
4.1、方法引用
符号表示:::
应用场景:Lambda所要实现的方法,已有其他相同的法法存在,则直接应用,避免冗余代码。 引用方式: 1、对象::方法名; 2、类名::静态方法名; 3、类名::方法名称; 4、类名::new; 调用的构造器 5、TypeName[]::new; 调用的数组构造器,比如:String[]::new
4.1.1、对象方法引用
注意:被引用的方法入参出参必须和接口一致
@SpringBootTest
public class MethodQuoteTest {
@Test
public void test() {
Date now=new Date();
// Supplier<Long> obj=()->{
// return now.getTime();
// };
Supplier<Long> obj=now::getTime;
Long long1 = obj.get();
System.out.println(long1);
}
}
4.1.2、静态方法引用
@Test
public void test2() {
Supplier<Long> obj=()->{
return System.currentTimeMillis();
};
System.out.println(obj.get());
Supplier<Long> obj2=System::currentTimeMillis;
System.out.println(obj2.get());
}
4.1.3、类名引用实例方法
@Test
public void test3() {
Function<String,Integer> obj=str->{
return str.length();
};
Integer apply = obj.apply("hao123");
System.out.println("apply:"+apply);
Function<String,Integer> obj2=String::length;
System.out.println("类名方法引用:"+obj.apply("hello world"));
}
4.1.4、类名::new引用类的无参构造器
@Test
public void hao11() {
Supplier<Person> obj=()->{
return new Person();
};
Supplier<Person> obj2=Person::new;
}
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;
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
}
4.1.5、类名::new引用类的有参构造器
@Test
public void hao12() {
BiFunction<String,Integer,Person> obj=(name,age)->{
return new Person(name,age);
};
BiFunction<String,Integer,Person> obj2=Person::new;
Person apply = obj2.apply("张三丰", 70);
System.out.println("有参构造:"+apply);
}
4.1.6、数组::new引用
@Test
public void hao1() {
Function<Integer,int[]> array=s->{
return new int[s];
};
int[] apply = array.apply(10);
System.out.println(Arrays.toString(apply));
Function<Integer,int[]> array2=int[]::new;
int[] apply2 = array2.apply(10);
System.out.println(Arrays.toString(apply2));
}