Collections的sort比较:Comparator、lambda expression、Comparator.comparing
1 | public class CollectionsSort { |
How?:JDK8的Runnable接口
1 | @FunctionalInterface |
只有一个抽象方法且标注@FunctionalInterface注解的接口才可以使用lambda expressions【Object类中的相同方法在接口的定义中除外-equals、toString等不影响@FunctionalInterface】。
Java 8 lambda expressions的实现和编译机制
不使用内部类实现的两个原因
- 性能:如果使用内部类,每个lambda表达式都会编译成字节码文件(class)存储在磁盘上,这些文件在JVM启动的时候被加载,会增加JVM的启动时间,因为所有的字节码文件都需要在使用之前进行首次加载和校验
- 可扩展:如果使用内部类,lambda在未来想要改变实现方式时会受到一定的限制
- CallSite
使用动态调用机制【Java7引入】
- 当使用javac编译代码的时候,它会捕捉到lambda表达式,然后生成一个invokedynamic(lambda工厂)CallSite,当invokedynamic callsite被调用时返回一个lambda表达式转化的函数式接口的实例
- Collections.sort的字节码
1 | public static void main(java.lang.String[]); |
lambda-translation
Java8提供的函数式接口:java.util.function
java.util.function.Predicate 条件检查:判断
1
2
3
4
5
6
7@FunctionalInterface
public interface Predicate<T> {
boolean test(T var1);
...
}
Predicate<String> namesStartingWithS = name -> name.startsWith("s");java.util.function.Consumer 只处理,无返回结果
1
2
3
4
5
6
7
8
9
10
11
12@FunctionalInterface
public interface Consumer<T> {
/**
* Performs this operation on the given argument.
*
* @param t the input argument
*/
void accept(T t);
}
Consumer<String> messageConsumer = message -> System.out.println(message);java.util.function.Function<T,R> 处理且有返回值
1
2
3
4
5
6
7
8
9
10
11
12
13@FunctionalInterface
public interface Function<T, R> {
/**
* Applies this function to the given argument.
*
* @param t the function argument
* @return the function result
*/
R apply(T t);
}
Function<String, String> toUpperCase = name -> name.toUpperCase();java.util.function.Supplier 没有参数,只有返回结果
1
2
3
4
5
6
7
8
9
10
11
12@FunctionalInterface
public interface Supplier<T> {
/**
* Gets a result.
*
* @return a result
*/
T get();
}
Supplier<String> uuidGenerator= () -> UUID.randomUUID().toString();
方法引用 Object::method
- method references 如 String::length and so on
- static method references 如 Collections::max
- instance method references 如 String::concat