Java2遍歷集合
遍歷Collection的代碼,可以是采用Iterator接口,通過next()遍歷。如:
1
2
3
4
5
6
|
List<String> list = Arrays.asList( "Hi" , "I" , "am" , "Henry.Yao" ); // 此處已經用到了泛型,不能算是純粹的Java2代碼,僅作Iterator示范 for (Iterator<String> it = list.iterator(); it.hasNext();) { String item = it.next(); System.out.println( "listItem = " + item); } |
輸出:
listItem = Hi
listItem = I
listItem = am
listItem = Henry.Yao
Java5遍歷集合
在Java5中,提供了增強的for循環,如:
1
2
3
4
|
List<String> list = Arrays.asList( "Hi" , "I" , "am" , "Henry.Yao" ); for (String item : list) { System.out.println( "listItem = " + item); } |
Java8遍歷集合
在Java8中,通過Lambda表達式提供了更簡潔的編程方式,如:
1
2
3
|
list.forEach(item -> { System.out.println( "listItem = " + item); }); |
需同時提供index,咋辦?
操作集合元素item的同時,如果還需要同時提供index值,咋辦?
思考后,我們可能大都寫出了如下的代碼,同時心有不甘:
1
2
3
4
5
|
List<String> list = Arrays.asList( "Hi" , "I" , "am" , "Henry.Yao" ); for ( int index; index<list.size(); index++) { String item = list.get(i); System.out.println( "list[" +index+ "] = " +item); } |
輸出:
list[0] = Hi,
list[1] = I
list[2] = am
list[3] = Henry.Yao
期望的遍歷模式
因為,如下的模式才是我們期望的模式
1
2
3
|
list.forEach((item, index) -> { System.out.println( "listItem = " + item); }); // Compile ERROR |
這只是期望。實際上,Jdk8并沒有提供該函數,直至Jdk11也均沒有提供該函數。
通過BiConsumer包裝Consumer實現
“沒有工具,我們制造工具” 定義如下的工具方法,基于這個工具方法,我們就能在遍歷集合,同時提供item和index值:
1
2
3
4
5
6
7
8
9
10
11
|
// 工具方法 public static <T> Consumer<T> consumerWithIndex(BiConsumer<T, Integer> consumer) { class Obj { int i; } Obj obj = new Obj(); return t -> { int index = obj.i++; consumer.accept(t, index); }; } |
這樣的業務代碼,是我期望的!
基于該工具方法,便可輕松編寫如下業務代碼,清晰、簡潔:
1
2
3
|
list.forEach(LambdaUtils.consumerWithIndex((item, index) -> { System.out.println( "list[" + index + "]=" + item); })); |
思考過程
這個工具方法的設計過程,也是參考借鑒了distinctByKey,如圖:
1
2
3
4
5
|
// 工具方法 public static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) { Map<Object, Boolean> seen = new ConcurrentHashMap<>(); return t -> Objects.isNull(seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE)); } |
1
2
3
|
// 業務代碼 // 從人員列表中過濾出一個子集(每個部門選一個人) employees.stream().filter(distinctByKey(Employee::getDeptCode)).collect(toList()); |
我們不僅要會使用工具,更要會制造工具…
我們的程序,不僅僅只是大片的業務代碼,更是需要抽象和提取出的諸多工具方法。
使用工具(使用Java和第三方提供的方法)到極致,那是高級程序員,
制造工具(分析和設計出項目的工具方法)到極致,那是高級設計師。
到此這篇關于詳解Java8的forEach(...)如何提供index值的文章就介紹到這了,更多相關Java8 forEach提供index值內容請搜索服務器之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持服務器之家!
原文鏈接:https://blog.csdn.net/weixin_37297850/article/details/102856739