1、取代匿名内部类

无参函数简写

如果需要新建一个线程,一种常见的写法是这样:

1
2
3
4
5
6
7
// JDK7 匿名内部类写法
new Thread(new Runnable(){// 接口名
@Override
public void run(){// 方法名
System.out.println("Thread run()");
}
}).start();

使用lambda进行无参函数的简写:

1
2
3
4
// JDK8 Lambda表达式写法
new Thread(
() -> System.out.println("Thread run()")// 省略接口名和方法名
).start();

如果函数体有多行,可以用大括号括起来:

1
2
3
4
5
6
new Thread(
() -> {
System.out.print("Hello");
System.out.println(" Hoolee");
}
).start();

有参函数简写

如果要给一个字符串列表通过自定义比较器,按照字符串长度进行排序,Java 7的书写形式如下:

1
2
3
4
5
6
7
8
9
10
11
12
// JDK7 匿名内部类写法
List<String> list = Arrays.asList("I", "love", "you", "too");
Collections.sort(list, new Comparator<String>(){// 接口名
@Override
public int compare(String s1, String s2){// 方法名
if(s1 == null)
return -1;
if(s2 == null)
return 1;
return s1.length()-s2.length();
}
});

上述代码通过内部类重载了Comparator接口的compare()方法,实现比较逻辑。采用Lambda表达式可简写如下:

1
2
3
4
5
6
7
8
9
// JDK8 Lambda表达式写法
List<String> list = Arrays.asList("I", "love", "you", "too");
Collections.sort(list, (s1, s2) ->{// 省略参数表的类型
if(s1 == null)
return -1;
if(s2 == null)
return 1;
return s1.length()-s2.length();
});

自定义函数接口

自定义函数接口很容易,只需要编写一个只有一个抽象方法的接口即可。

1
2
3
4
5
// 自定义函数接口
@FunctionalInterface
public interface ConsumerInterface<T>{
void accept(T t);
}

上面代码中的@FunctionalInterface是可选的,但加上该标注编译器会帮你检查接口是否符合函数接口规范。就像加入@Override标注会检查是否重载了函数一样。

有了上述接口定义,就可以写出类似如下的代码:

1
ConsumerInterface<String> consumer = str -> System.out.println(str);

进一步的,还可以这样使用:

1
2
3
4
5
6
7
8
9
10
11
class MyStream<T>{
private List<T> list;
...
public void myForEach(ConsumerInterface<T> consumer){// 1
for(T t : list){
consumer.accept(t);
}
}
}
MyStream<String> stream = new MyStream<String>();
stream.myForEach(str -> System.out.println(str));// 使用自定义函数接口书写Lambda表达式

参考:https://www.cnblogs.com/CarpenterLee/p/5978721.html