lambda是一個(gè)匿名的函數(shù)宝剖,可以將它作為參數(shù)傳遞或者返回一個(gè)lambda,當(dāng)提到lambda就不得不提到Functional Interfaces.
那么什么是Functional Interfaces笤喳?
我們首先看下java.util.function這個(gè)package得糜,這里面都是java提供給我們的Functional Interface,他們都是注解了@FunctionalInterface
從java提供的package中症概,我們發(fā)現(xiàn)要想自定義一個(gè)實(shí)現(xiàn)lambda功能的Interface伪节,首先要使用@FunctionalInterface注解這個(gè)Interface光羞。實(shí)際上只要自定義的Interface只有一個(gè)abstract(未實(shí)現(xiàn))的方法時(shí),我們都可以不用添加@FunctionalInterface這個(gè)注解怀大。
但是我們?cè)谝粋€(gè)project中纱兑,建議還是添加這個(gè)@FunctionalInterface來表示這個(gè)Interface是一個(gè)Functional的,同時(shí)也可以避免往這個(gè)Interface里面誤添加其他的abstract方法化借,如果你使用@FunctionalInterface注解的話潜慎,會(huì)報(bào)編譯錯(cuò)誤(Functional只支持一個(gè)abstract方法)
Lambda就是代替了Inner class嗎?
從之前的實(shí)現(xiàn)和使用Lambda的實(shí)現(xiàn)來看蓖康,看起來確實(shí)像是代替了Inner class铐炫,但是lambda和Inner class他們有不同的scope。
- Inner class:enclosing scope(括號(hào))可以定義同名字的局部變量覆蓋成員變量蒜焊,this關(guān)鍵字是指向Inner class的
- lambda:enclosing scope(括號(hào))是不可以覆蓋外面的變量倒信,this指向class的
另外lambda作為一個(gè)純函數(shù),理論上是不允許修改外部的state的泳梆,所以外部的變量是不可以改變(final)鳖悠,但不一定非得定義final,換一個(gè)詞語是"effectively final"优妙,只被賦值了一次的乘综。如果lambda內(nèi)檢測(cè)到賦值了多次,會(huì)報(bào)編譯錯(cuò)誤套硼。但是在某些情況下卡辰,他有可以修改,如:
int[] total = new int[1];
Runnable r = () -> total[0]++;
r.run();
這段代碼是合法的邪意,沒有報(bào)錯(cuò)九妈,total變量確實(shí)是"effectively final"的,在lambda內(nèi)沒有對(duì)他進(jìn)行重新賦值雾鬼,但是我們對(duì)他內(nèi)部的值進(jìn)行了修改C戎臁!呆贿!在以后的編碼中一定要避免上述代碼的出現(xiàn)
JAVA 8中常用的幾種FunctionalInterface
-
Functions: 接收一個(gè)參數(shù)嚷兔,返回另外一個(gè)值。另外如果要接收兩個(gè)參數(shù)做入,一般Interface要包含"Bi"關(guān)鍵詞冒晰,比如BiFunction,ToDoubleBiFunction竟块,ToIntBiFunction...
@FunctionalInterface public interface Function<T, R> { R apply(T t); ... } //例子: Map<String, Integer> nameMap = new HashMap<>(); Integer value = nameMap.computeIfAbsent("John", s -> s.length()); //或者換種寫法 Integer value = nameMap.computeIfAbsent("John", String::length);
-
Suppliers: 不需要接收參數(shù)壶运,但是要返回一個(gè)值
@FunctionalInterface public interface Supplier<T> { T get(); //例子: public double squareLazy(Supplier<Double> lazyValue) { return Math.pow(lazyValue.get(), 2); } Supplier<Double> lazyValue = () -> { Uninterruptibles.sleepUninterruptibly(1000, TimeUnit.MILLISECONDS); return 9d; }; Double valueSquared = squareLazy(lazyValue);
-
Consumers: 和Suppliers相反,接收一個(gè)參數(shù)浪秘,但是不返回
@FunctionalInterface public interface Consumer<T> { void accept(T t); ... } //例子: List<String> names = Arrays.asList("John", "Freddy", "Samuel"); names.forEach(name -> System.out.println("Hello, " + name));
-
Predicates: 接收一個(gè)參數(shù)蒋情,返回一個(gè)boolean值
@FunctionalInterface public interface Predicate<T> { boolean test(T t); ... } //例子 List<String> names = Arrays.asList("Angela", "Aaron", "Bob", "Claire", "David"); List<String> namesWithA = names.stream() .filter(name -> name.startsWith("A")) .collect(Collectors.toList());
-
Operators: 接收參數(shù)和返回值,是同一個(gè)類型耸携。它是一個(gè)特殊的Function類型的interface
@FunctionalInterface public interface UnaryOperator<T> extends Function<T, T> { static <T> UnaryOperator<T> identity() { return t -> t; } //例子 List<String> names = Arrays.asList("bob", "josh", "megan"); names.replaceAll(name -> name.toUpperCase());