JDK8的新特性
這兩天開始看jdk8的新特性,先看了Lembda表示式和Stream,就一個感覺,優雅。
趕緊將這兩天的成果總結一下
一、Lembda表示式
Lembda表示式格式
lembda表示式是一個簡潔、可傳遞的匿名函式,實現了把程式碼塊賦值給一個變數的功能
格式就是 (parameters) -> expression
,需要注意的是:
- 引數可以為空 ()->xxx
- 引數為一個值得時候,可以省略引數的括號 x->xxx
- 表示式只有一行的時候不需要
;
,有多行的時候需要加上;
- 表示式可以是一個數字(直接返回這個數字),一個算式;可以是普通的一個語句(無返回,相當於void)
- 引數的名不能和區域性變數相同
- 表示式中直接呼叫的變數(不是傳入的),必須是顯示宣告為final或事實上的final型別
函式式介面
lambda表示式的使用需要藉助於函式式介面
含有且僅含有一個抽象方法的介面被稱為函式式介面
- 需要注意的是,
default
關鍵字可以在介面中定義實現,
如果一個介面含有多個實現但是隻有一個抽象方法,那麼它也屬於函式式介面,另外static方法也可以存在於函式式介面
自定義函式式介面
一般用@FunctionInterface
對函式式介面來進行語義化標註
步驟:
- 定義一個函式式介面
@FunctionalInterface
public interface Append {
int append(int a,int b);
}
public static void main(String[] args) {
//對這個介面的抽象方法進行實現,並用該介面進行接收
Append append = ((a, b) -> a + b);
//呼叫這個方法
int result = append.append(1, 2);
System.out.println("result = "+result);
}
- 對這個介面的抽象方法進行實現,並用該介面進行接收,
- 呼叫這個方法
結果: result = 3
JDK自帶的函式式介面
- Predicate
- Consumer
- Function<T, R> 方法
R apoly(T t);
執行轉換操作,輸入型別 T 的資料,返回 R 型別的結果
這三個是最重要的介面,Stream也用到這些介面,下面我強行使用這三個介面
/*Predicate<T> 判斷*/
Predicate<String> stringPredicate = str -> StringUtils.isBlank(str) || "error".equalsIgnoreCase(str);
/*Consumer<T>*/
Consumer<String> stringConsumer = str -> {
if (StringUtils.isBlank(str) || "error".equalsIgnoreCase(str)) {
System.out.println("Consumer失敗");
}
};
/*Function<T,R>*/
Function<String, String> stringStringFunction = str -> {
if (StringUtils.isBlank(str) || "error".equalsIgnoreCase(str)) {
return "Function失敗";
} else {
return "Function成功";
}
};
String in = "error";
if (stringPredicate.test(in)) {
System.out.println("Predicate失敗");
}
stringConsumer.accept(in);
System.out.println(stringStringFunction.apply(in));
方法引用
在表示式中,可以使用::
更方便的呼叫方法,它會自動將引數傳入,並且將返回值返回
比如
System.out.println(傳入引數)
可以轉換為System.out::println
表示式只需要呼叫一個方法就可以完成功能的時候,可以用這種方法來進一步簡化程式碼;
二.Stream流
Stream使用上面說的JDK自帶的函式式介面
Stream是一種函數語言程式設計對集合,陣列,I/O channel, 產生器generator等資料的操作方式,它有以下特點:
- 無儲存,Stream本身不會儲存資料
- 不會修改傳入的資料來源
- 惰性執行:Stream上的操作不會立即執行,而是會在真正需要的時候進行
- 可消費性:Stream只能被消費一次,類似迭代器,想要再次遍歷,必須生成新的Stream.
在學習過程中,我發現Stream某些操作之後返回的仍然是流,而有些操作返回的確實真實的被處理之後資料,Stream的操作可以據此分為兩種
- 中間操作 總是會惰式執行,呼叫中間操作只會生成一個標記了該操作的新stream。
- 結束操作 會觸發實際計算,計算髮生時會把所有中間操作積攢的操作以pipeline的方式執行,這樣可以減少迭代次數。計算完成之後stream就會失效。
總之,把Stream看做一根水管就好啦,一開始把一根根水管拼接起來(中間操作),安裝一個水龍頭(結束操作),確認有水龍頭之後水就依次通過水管,最後通過水龍頭進入下水道(不能重複使用);
Collection.stream() 或者 Collection.parallelStream() 來建立一個序列Stream或者並行Stream。
常用的Stream方法
中間操作
sorted排序
Stream<T> sorted();
Stream<T> sorted(Comparator<? super T> comparator);
這是一個有狀態的操作
用法|作用
—|—
sorted()|自然排序
sorted(Comparator.reverseOrder()) |自然逆向排序
sorted(Comparator.comparing(Student::getAge)) |通過某些元素排序
sorted(Comparator.comparing(Student::getAge).reversed()) |通過某些元素逆向排序
Comparator是比較器
map元素操作
<R> Stream<R> map(Function<? super T, ? extends R> mapper);
用於對每個元素進行操作,並且將處理後的Stream返回
例如map(i->i*2)
將所有資料進行平方操作
filter過濾
Stream<T> filter(Predicate<? super T> predicate);
入參為Predicate,lembda表示式返回值是boolean;
如果表示式為flase,則剔除資料,只留符合條件的
過濾是中間操作:Stream<Integer> integerStream = intList.stream().filter(i -> i > 4);
limit限制
Stream<T> limit(long maxSize);
限制資料的數量,這是一個有狀態的短路的操作。
distinct去重
Stream<T> distinct();
去除重複的操作,這是一個有狀態的操作
結束操作
forEach迭代
void forEach(Consumer<? super T> action);
入參是Consumer,表示式不需要返回值,方法本身返回值void,所以是結束操作
常用的方法是forEach(System.out::println);
collect存入容器
<R, A> R collect(Collector<? super T, A, R> collector);
將資料存入一個Collection或Map
toArray存入陣列
Object[] toArray();
將結果存入一個陣列中
count計數
long count();
計算流中元素的數量
max 和 min
Optional<T> min(Comparator<? super T> comparator);
Optional<T> max(Comparator<? super T> comparator);
根據一個比較器找到最大或最小元素
anyMatch allMatch noneMatch 匹配
boolean anyMatch(Predicate<? super T> predicate);
三個都一樣
是否至少有一個元素匹配
是否每一個元素都匹配
是否沒有元素匹配
findFirst findAny 查詢
Optional<T> findFirst();
查詢第一個元素
查詢隨機的一個元素
還有其他流
在Stream中我發現mapToInt
這個方法返回值是另一個流,也有相應的方法,比較好用的就是sum()
求和等,回頭再翻原始碼
常用的
-
List轉Map
Map<Integer, A> aMap = aList.stream().collect(Collectors.toMap(A::getId, a -> a,(k1,k2)->k1));
-
一個獲取隨機數的方法
random.ints().limit(10).forEach(System.out::println);
未完待續
參考資料:
- https://blog.csdn.net/chenhao_c_h/article/details/80691284
- https://www.cnblogs.com/pikachu-zhaof/p/9724826.html