【摘要】 Lambad表达式
1.0 Lambda使用的条件
方法的参数是接口,就可以考虑使用Lambda表达式来代替匿名内部类,但不是所有情况都可以是用Lambda表达式。 使用前提条件: 1、方法的参数或局部变量类型必须为接口才能使用; 2、接口中有且仅有一个抽象方法(函数式接口); 补充说明:Lambda表达式的类不可以直接反编译; 工作原理:Lambda表达式会在类里…
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));
}
文章来源: blog.csdn.net,作者:500年,版权归原作者所有,如需转载,请联系作者。
原文链接:blog.csdn.net/Asia1752/article/details/115800014