Java8
中
Map
添加的新方法
computeIfAbsent
來統計集合中每一個元素出現的全部位置,代碼以下:
public static Map<String, List<Integer>> getElementPositions(List<String> list) {
Map<String, List<Integer>> positionsMap = new HashMap<>();
for (int i = 0; i < list.size(); i++) {
positionsMap.computeIfAbsent(list.get(i), k -> new ArrayList<>(1)).add(i);
}
return positionsMap;
}
複製代碼
至少有兩點須要探討: 一、若是 list
不是基於數組的(即不是 RandomAccess
的),而是基於鏈表的,那麼 list.get(int index)
方法的效率就值得思考了; 二、既然都有了 Lambda(即當前平臺爲 Java8),咱們爲何還要一次次去寫傳統的 for 循環呢?java
在 Java8
中,爲 Iterable
接口添加了默認的 forEach
方法:git
Iterable
中全部的元素,使用每一個元素做爲參數調用一次
action
。而
Collection
接口繼承了
Iterable
接口,因此全部的繼承自
Collection
的集合類均可以直接調用
forEach
方法。好比:
public static void main(String[] args) throws Exception {
List<String> list = Arrays.asList("a", "b", "b", "c", "c", "c", "d", "d", "d", "f", "f", "g");
list.forEach(str -> System.out.print(str + " "));
System.out.println();
}
複製代碼
運行結果: github
那若是咱們在遍歷的時候須要使用到元素的索引呢(相似 getElementPositions
方法那樣)? 很惋惜,Java8
的 Iterable
並無提供一個帶索引的 forEach
方法。不過本身動手,豐衣足食——讓咱們本身寫一個帶索引的 forEach
方法:面試
import java.util.Objects;
import java.util.function.BiConsumer;
/**
* Iterable 的工具類
*/
public class Iterables {
public static <E> void forEach(
Iterable<? extends E> elements, BiConsumer<Integer, ? super E> action) {
Objects.requireNonNull(elements);
Objects.requireNonNull(action);
int index = 0;
for (E element : elements) {
action.accept(index++, element);
}
}
}
複製代碼
該 forEach
方法第一個參數爲要遍歷的 Iterable
,第二個參數爲 BiConsumer
。BiConsumer
的輸入參數第一個即索引,第二個爲元素。算法
咱們測試下這個 forEach
方法:編程
public static void main(String[] args) throws Exception {
List<String> list = Arrays.asList("a", "b", "b", "c", "c", "c", "d", "d", "d", "f", "f", "g");
Iterables.forEach(list, (index, str) -> System.out.println(index + " -> " + str));
}
複製代碼
運行結果: segmentfault
結果和預期的一致。數組
如今咱們使用 Iterables.forEach
改寫 getElementPositions
方法:bash
public static Map<String, List<Integer>> getElementPositions(List<String> list) {
Map<String, List<Integer>> positionsMap = new HashMap<>();
Iterables.forEach(list, (index, str) -> {
positionsMap.computeIfAbsent(str, k -> new ArrayList<>(1)).add(index);
});
return positionsMap;
}
public static void main(String[] args) throws Exception {
List<String> list = Arrays.asList("a", "b", "b", "c", "c", "c", "d", "d", "d", "f", "f", "g");
System.out.println("使用 computeIfAbsent 和 Iterable.forEach:");
Map<String, List<Integer>> elementPositions = getElementPositions(list);
System.out.println(elementPositions);
}
複製代碼
運行結果和原來一致: 微信
真的不明白這麼簡單且實用的方法,Java8
爲何不在 Iterable
中提供一個默認實現(此處應有黑人問號)。
原文做者:mizhoux 原文地址:segmentfault.com/a/119000000…
大廠筆試內容集合(內有詳細解析) 持續更新中....
歡迎關注我的微信公衆號:Coder編程 歡迎關注Coder編程公衆號,主要分享數據結構與算法、Java相關知識體系、框架知識及原理、Spring全家桶、微服務項目實戰、DevOps實踐之路、每日一篇互聯網大廠面試或筆試題以及PMP項目管理知識等。更多精彩內容正在路上~ 新建了一個qq羣:315211365,歡迎你們進羣交流一塊兒學習。謝謝了!也能夠介紹給身邊有須要的朋友。
文章收錄至 Github: github.com/CoderMerlin… Gitee: gitee.com/573059382/c… 歡迎關注並star~
![]()