前言
在说lambda表达式前,说一下java的一些编程技巧思考:
- 对象作为参数,无需返回值:设置全局变量,我们有时候编写一些方法不需要返回值,将传递的参数变量填充完毕,然后直接返回。因为我们传递的参数可以是类也可以是对象。
- 回调方式:上面的这种写法可以改写成回调方式,就是将对象的引用作为参数传递给方法,然后在执行自己的逻辑完毕之后,执行对象引用参数的回调方法。Java中的回调机制
- 观察者模式:而上面的回调机制这种反向调用,在观察者模式中体现更加明显,将主题对象引用传递给观察者,观察者在建立与主题关系的时候,就会将观察者自身引用传递给主题,主题就可以反向操作观察者,主题发生变化,观察者也就发生了变化。
- 上面这些编程技巧,都是将参数对象化引用,而我们也可以传递一个接口参数,就是行为化参数,具体实现也将延迟到当前方法中去实现。java也提供了匿名内部类这种写法,保障了行为化参数,而现在lambda表达式可以将这种匿名内部类进行简化。
lambda表达式写法
样例:
- 要不参数都显式类型,要不参数都隐式类型。
lambda处理泛型接口
将List内容转换类型:
# 定义类型转换接口,T为参数类型,K为返回值类型
@FunctionalInterface
public interface TypeConvertFunction<T, K> {
K convert(T t);
}
# 实现
public static <T, K> List<K> convertList(List<T> list, TypeConvertFunction<T, K> function) {
List<K> resultList = new ArrayList<>();
list.forEach(t -> resultList.add(function.convert(t)));
return resultList;
}
测试:
public static void main(String[] args) {
List<Date> dateList = new ArrayList<>();
dateList.add(new Date(120, 0, 10));
dateList.add(new Date(102, 1, 22));
dateList.add(new Date(122, 5, 18));
dateList.add(new Date(3, 11, 26));
List<String> dateStrs = LambdaTest.convertList(dateList, (Date date) -> date.toString());
dateStrs.forEach(dateStr -> System.out.println(dateStr));
}
方法调用
调用无参构造方法
使用lambda的方法接口注解方式
- 写法1:
Supplier<User> userSupplier = () -> new User();
- 写法2:
Supplier<User> userSupplier = User::new;
至于Supplier方法接口实现:
调用有参构造方法
Supplier<User> userSupplier = () -> new User("张三");
调用静态方法
public static void main(String[] args) {
/**
* 无参无返回值静态方法
*/
Runnable runnable1 = () -> {
User.printVal();
};
runnable1.run();
Runnable runnable2 = User::printVal;
runnable2.run();
/**
* 无参有返回值静态方法
*/
Supplier<String> supplier1 = () -> {
return User.retVal();
};
System.out.println(supplier1.get());
Supplier<String> supplier2 = User::retVal;
System.out.println(supplier2.get());
/**
* 有参无返回值静态方法
*/
Consumer<User> consumer1 = user -> User.printUser(user);
consumer1.accept(new User("张三"));
Consumer<User> consumer2 = User::printUser;
consumer2.accept(new User("张三"));
/**
* 有参有返回值静态方法
*/
Function<User, String> function1 = user -> User.retValByUser(user);
System.out.println(function1.apply(new User("李四")));
Function<User, String> function2 =User::retValByUser;
System.out.println(function2.apply(new User("李四")));
}
调用普通方法
/**
* 无参无返回值实例方法
*/
Runnable runnable1 = () -> {
new User().method1();
};
runnable1.run();
Runnable runnable2 = new User()::method1;
runnable2.run();
/**
* 无参有返回值实例方法
*/
Supplier<String> supplier1 = () -> {
return new User().method2();
};
System.out.println(supplier1.get());
Supplier<String> supplier2 = new User()::method2;
System.out.println(supplier2.get());
/**
* 有参无返回值实例方法
*/
Consumer<String> consumer1 = (name) -> {
new User().method3(name);
};
consumer1.accept("张三");
Consumer<String> consumer2 = new User()::method3;
consumer2.accept("张三");
/**
* 有参有返回值实例方法
*/
Function<Integer, String> function1 = val -> {
return new User().method4(val);
};
System.out.println(function1.apply(10));
Function<Integer, String> function2 = new User()::method4;
System.out.println(function2.apply(11));
}
说明:
调用无返回值:使用Runnable接口
调用有返回值:使用Supplier接口
调用有返回值有参数:使用Function接口
改造匿名内部类
-
lambda改造集合排序Comparator写法:
老写法: lambda改造sortDate新写法:
public static void sortDate(List<Date> dateList) {
Collections.sort(dateList, (d1, d2) -> {
if (d1.before(d2)) {
return -1;
}
if (d1.after(d2)) {
return 1;
}
return 0;
});
}
-
线程Runnable改造写法:
老写法:
lambda改造exeThread新写法:
public static void exeThread() {
new Thread(() -> System.out.println(Thread.currentThread().getName())).start();
}
参考
《java8 实战》
java8官网:
https://docs.oracle.com/javase/specs/jls/se8/html/index.html
网友评论