java8新特性 (λ、stream 與 預設介面方法)
阿新 • • 發佈:2019-02-09
1.lambda
λ表示式本質上是一個匿名方法,用來方便地實現函式介面。也就是說,λ表示式主要用於替換以前廣泛使用的內部匿名類。
讓我們來看下面這個例子:
public int add(int x, int y) {
return x + y;
}
轉成λ表示式後是這個樣子:
(int x, int y) -> x + y;
引數型別也可以省略,Java編譯器會根據上下文推斷出來:
(x, y) -> x + y; //返回兩數之和
或者
(x, y) -> { return x + y; } //顯式指明返回值
λ表示式由三部分組成:引數列表
λ表示式的型別,叫做“目標型別(target type)。λ表示式的目標型別是“函式介面(functional interface),這是Java8新引入的概念。它的定義是:一個介面,如果只有一個顯式宣告的抽象方法,那麼它就是一個函式介面。一般用@FunctionalInterface標註出來(也可以不標)。舉例如下:
public interface Runnable { void run(); }
public interface Comparator<T> { int compare(T o1, T o2);}
lambda不是匿名內部類的語法糖,見下。import java.util.Arrays; import java.util.Collections; import java.util.List; public class A { public int a = 10; public static void main(String[] args) { List namesList = Arrays.asList("peter", "anna", "mike", "xenia", "xiaoMing"); Collections.sort(namesList, (a, b) -> (a.length() - b.length())); System.out.println(namesList); namesList.forEach((o) -> { System.out.println(o); }); System.out.println(); new Thread(() -> { System.out.println("Hello Lambda!"); }).start(); //anonymous class Thread oldSchool = new Thread(new Runnable() { @Override public void run() { System.out.println("This is from an anonymous class."); } }); oldSchool.start(); } } /* * [anna, mike, peter, xenia, xiaoMing] anna mike peter xenia xiaoMing * * Hello Lambda! This is from an anonymous class. */
package com.yichudu; public class A { public static void main(String[] args) { //使用匿名內部類,編譯後會有A$1.class的存在 Thread t1=new Thread(new Runnable() { @Override public void run() { System.out.print(123); } } ); //use lambda expression,no extra class generates. Thread t2=new Thread(()->{System.out.print(123);}); } }
2.stream
Stream<E> java.util.Collection.stream()返回Stream物件。
Stream<T> java.util.stream.Stream.filter(Predicate<? super T> predicate)
從stream中過濾元素,返回的stream由與謂詞匹配的元素組成。
void java.util.stream.Stream.forEach(Consumer<? super T> action)
對stream中的每一個元素執行action。 boolean java.util.function.Predicate.test(T t)
Predicate介面中的方法,評估給定元素是否滿足謂詞。 void java.util.function.Consumer.accept(T t)
Consumer介面中的方法,此方法對給定的元素進行操作。
public class Apple {
public int weight = 2;
public Apple(){}
public Apple(int x){
weight=x;
}
public static void main(String[] args) {
List fruits = Arrays.asList(new Apple(), new Apple(),new Apple(3));
//過濾出重量為2的蘋果,並將這些蘋果重量設為1
fruits.stream().filter(s -> s.weight == 2).forEach(s -> s.weight = 1);
//得到最沉的蘋果
Apple heaviestApple=fruits.stream().max((a,b)->(a.weight-b.weight)).get();
heaviestApple.weight=4;
//求出所有蘋果的重量之和
int sum=fruits.stream().mapToInt(o->o.weight).sum();
//輸出驗證
fruits.forEach(o -> System.out.print(o.weight));
}
}
// 114
3.預設介面方法
通過default關鍵字給介面的方法提供預設實現。 這樣與抽象類的普通方法就差別不大了。 java.util.Collection介面的原始碼含有下面的預設介面實現。default Stream<E> stream() {
return StreamSupport.stream(spliterator(), false);
}