Java Lambda Collection/List篇
Java Lambda Collection/List篇
前言
這篇文章主要接續Lambda基礎篇,主要介紹與自我複習常用的Collection家族中的Lambda方法
Collection
forEach
forEach 是Iterable介面中的default Method原始碼如下
default void forEach(Consumer<? super T> action) {
Objects.requireNonNull(action);
for (T t : this) {
action.accept(t);
}
}
敲黑板 畫重點
- Collection透過FunctionalInterface "Consumer"讓此介面可以透過lambda實踐。
- Collection家族都有實作Iterable介面因此都可以使用此forEach方法。
實踐
private void forExample(List<String> example) {
example.forEach(System.out::println);
}
透過ArrayList實踐
- System.out::println省列了不帶任何參數的method ()->,讓Lambda自動對物件使用此method
removeIf
removeIf是Collection介面本身的方法,原始碼如下
default boolean removeIf(Predicate<? super E> filter) {
Objects.requireNonNull(filter);
boolean removed = false;
final Iterator<E> each = iterator();
while (each.hasNext()) {
if (filter.test(each.next())) {
each.remove();
removed = true;
}
}
return removed;
敲黑板 畫重點
- 我們看到Predicate<? super E>這個方法,他後面的<? super E>稱為限制符,傳入的物件必須是E這個template的子類別(或是本身)
實踐
private void removeExample() {
List<String> example = new ArrayList<>(Arrays.asList("data", "data2", "data"));
example.removeIf("data2"::equals);
System.out.println(example.toString());
}
透過ArrayList實踐
- 刪除列中的data2字串
如果是以前的寫法則可能要自己寫一串的for/while去找出此字串,現在lambda讓你輕輕鬆鬆解決
replaceAll
replaceAll method主要定義在List介面,可以對目前的物件做side effect,換句話說可以透過此lambda方法將此collection中的物件做額外的處理,原始碼如下
default void replaceAll(UnaryOperator<E> operator) {
Objects.requireNonNull(operator);
final ListIterator<E> li = this.listIterator();
while (li.hasNext()) {
li.set(operator.apply(li.next()));
}
}
敲黑板 畫重點
-
replcaceAll方法主要是傳入UnaryOperator介面,依照名稱來解析就是我只對單個物件做操作,而其中的ListIterator則是Iterator介面的擴增,讓這個迭代介面更貼近List的迭代(基本的Iterator是符合每個Collection家族的而此ListIteratpor是專門給List系列的物件),可以看到原始碼使用了ListIteraotr的set方法,這是母介面Iterator沒有提供的。
-
可以看到在這裡的ListIterator只是單純的介面,他必須依賴目前子類別的this.listIterator方法,因為接下來的範例是以ArrayList進行所以就是依據ArrayList的實作為主,而li.set傳入的operator則是你於外層lambda的邏輯並且傳入迭代的下個物件。
實作
private void replaceAllExample() {
List<String> example = new ArrayList<>(Arrays.asList("data", "data", "data"));
example.replaceAll(x ->
x = x + "- hi"
);
System.out.println(example.toString());
- 簡單的執行邏輯,對每個此ArrayList的字串增加hi字尾。
sort
如同replaceAll定義於List介面,可以對此List的物件做排序。原始碼如下
default void sort(Comparator<? super E> c) {
Object[] a = this.toArray();
Arrays.sort(a, (Comparator) c);
ListIterator<E> i = this.listIterator();
for (Object e : a) {
i.next();
i.set((E) e);
}
敲黑板 畫重點
-
此方法主要傳入的參數是Comparator介面,就如同一般使用Comaprator方法撰寫lambda就好(兩個物件間的比對),在方法中可以看到使用Arrays進行sort並將Comparator邏輯傳入,Arrays是Java提供專門對Array系列物件做處理的工具(只要底層是用陣列儲存操作就可以算是Array系列)
-
而迭代方法如同replaceAll使用List加強版的Iterator
實作
private void sortExample() {
List<String> example = new ArrayList<>(Arrays.asList("data1", "data12", "data123"));
example.sort((str1, str2) -> str2.length() - str1.length());
System.out.println(example.toString());
}
結論
其實Collection/List中還有非常非常多的Lambda使用,只是目前我自己最常使用的就是上面列出的。未來如果有更深入的心得會持續補上文章
留言
張貼留言