摘要:比如運行結果那如果我們在遍歷的時候需要使用到元素的索引呢類似方法那樣很可惜,的并沒有提供一個帶索引的方法。的輸入參數第一個即索引,第二個為元素。我們測試下這個方法運行結果結果和預期的一致。
在 上一篇文章 中,我們討論了如何使用 Java8 中 Map 添加的新方法 computeIfAbsent 來統計集合中每個元素出現的所有位置,代碼如下:
public static Map> getElementPositions(List list) { Map > positionsMap = new HashMap<>(); for (int i = 0; i < list.size(); i++) { positionsMap.computeIfAbsent(list.get(i), k -> new ArrayList<>(1)).add(i); } return positionsMap; }
至少有兩點需要探討:
1、如果 list 不是基于數組的(即不是 RandomAccess 的),而是基于鏈表的,那么 list.get(int index) 方法的效率就值得思考了;
2、既然都有了 Lambda(即當前平臺為 Java8),我們為什么還要一次次去寫傳統的 for 循環呢?
在 Java8 中,為 Iterable 接口添加了默認的 forEach 方法:
很好理解,遍歷當前 Iterable 中所有的元素,使用每個元素作為參數調用一次 action。而 Collection 接口繼承了 Iterable 接口,所以所有的繼承自 Collection 的集合類都可以直接調用 forEach 方法。比如:
public static void main(String[] args) throws Exception { Listlist = Arrays.asList("a", "b", "b", "c", "c", "c", "d", "d", "d", "f", "f", "g"); list.forEach(str -> System.out.print(str + " ")); System.out.println(); }
運行結果:
那如果我們在遍歷的時候需要使用到元素的索引呢(類似 getElementPositions 方法那樣)?
很可惜,Java8 的 Iterable 并沒有提供一個帶索引的 forEach 方法。不過自己動手,豐衣足食 —— 讓我們自己寫一個帶索引的 forEach 方法:
import java.util.Objects; import java.util.function.BiConsumer; /** * Iterable 的工具類 */ public class Iterables { public staticvoid forEach( Iterable extends E> elements, BiConsumer 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 { Listlist = Arrays.asList("a", "b", "b", "c", "c", "c", "d", "d", "d", "f", "f", "g"); Iterables.forEach(list, (index, str) -> System.out.println(index + " -> " + str)); }
運行結果:
結果和預期的一致。
現在我們使用 Iterables.forEach 改寫 getElementPositions 方法:
public static Map> getElementPositions(List list) { Map > 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 list = Arrays.asList("a", "b", "b", "c", "c", "c", "d", "d", "d", "f", "f", "g"); System.out.println("使用 computeIfAbsent 和 Iterable.forEach:"); Map > elementPositions = getElementPositions(list); System.out.println(elementPositions); }
運行結果和原來一致:
真的不明白這么簡單且實用的方法,Java8 為什么不在 Iterable 中提供一個默認實現(此處應有黑人問號)。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/66372.html
摘要:大家好,我是樂字節的小樂。需要注意的是很多流操作本身就會返回一個流,所以多個操作可以直接連接起來,如下圖這樣,操作可以進行鏈式調用,并且并行流還可以實現數據流并行處理操作。為集合創建并行流。 大家好,我是樂字節的小樂。說起流,我們會聯想到手機、電腦組裝流水線,物流倉庫商品包裝流水線等等,如果把手機 ,電腦,包裹看做最終結果的話,那么加工商品前的各種零部件就可以看做數據源,而中間一系列的...
摘要:需要注意的是很多流操作本身就會返回一個流,所以多個操作可以直接連接起來,如下圖這樣,操作可以進行鏈式調用,并且并行流還可以實現數據流并行處理操作。為集合創建并行流。 上一篇文章,小樂給大家介紹了《Java8新特性之方法引用》,下面接下來小樂將會給大家介紹Java8新特性之Stream,稱之為流,本篇文章為上半部分。 1、什么是流? Java Se中對于流的操作有輸入輸出IO流,而Jav...
摘要:靜態初始化簡化的語法格式動態初始化動態初始化只指定數組的長度,由系統為每個數組元素指定初始值。也就是說,數組引用變量是訪問堆內存中數組元素的根本方式。 順序結構 程序從上到下逐行地執行,中間沒有任何判斷和跳轉。 分支結構 if條件語句 if語句使用布爾表達式或布爾值作為分支條件來進行分支控制。 第一種形式: if(logic expression) { ...
摘要:很多語言等從設計之初就支持表達式。注意此時外部局部變量將自動變為作為方法返回值例子返回判斷字符串是否為空判斷字符串是否為空今天關于新特性表達式就講到這里了,接下來我會繼續講述新特性之函數式接口。 上一篇文章我們了解了Java8新特性-接口默認方法,接下來我們聊一聊Java8新特性之Lambda表達式。 Lambda表達式(也稱為閉包),它允許我們將函數當成參數傳遞給某個方法,或者把代碼...
摘要:數據流教程原文譯者飛龍協議這個示例驅動的教程是數據流的深入總結。但是的數據流是完全不同的東西。數據流是單體,并且在函數式編程中起到重要作用。列表上的所有流式操作請見數據流的。基本的數據流使用特殊的表達式,例如,而不是,而不是。 Java 8 數據流教程 原文:Java 8 Stream Tutorial 譯者:飛龍 協議:CC BY-NC-SA 4.0 這個示例驅動的教程是J...
閱讀 2343·2021-11-23 09:51
閱讀 1146·2021-11-22 13:52
閱讀 3620·2021-11-10 11:35
閱讀 1198·2021-10-25 09:47
閱讀 3005·2021-09-07 09:58
閱讀 1068·2019-08-30 15:54
閱讀 2825·2019-08-29 14:21
閱讀 3036·2019-08-29 12:20