[英]java-stream, map, keys not related to object
所以我有一個insIds的整數列表,從中我可以得到一個ABC列表,我想將它們映射到map中的一個條目(注意,我們不能從Abc.getIns中獲取getInsId)
這就是我想要的:(但是由於我們沒有 getInsId,所以我們無法以這種方式編寫)
Map<Integer, Integer> insIdToAbcId = abcController
.findAbcsByInsIds(insIds)
.stream()
.collect(Collectors.toMap(Abc::getInsId,
Abc::getAbcId));
我不確定如何編寫它以具有所需的映射關系。
已知整數列表: insIds
已知函數將采用insIds並返回列表:
abcController.findAbcsByInsIds(insIds)
然后是我不確定的問題:如何將insId映射到AbcId
(預期輸出: Map<Integer, Integer> insIdToAbcId
)
如果insIds
的項目與findAbcsByInsIds()
的結果之間存在有序的一對一關系,則可以按索引加入列表:
List<Abc> abcs = abcController.findAbcsByInsIds(insIds);
Map<Integer, Integer> insIdToAbcId = IntStream.range(0, insIds.size())
.boxed()
.collect(Collectors.toMap(insIds::get, i -> abcs.get(i).getAbcId()));
這是Stream不是正確解決方案的問題的主要示例。
在findAbcsByInsIds()
調用之后,您將獲得兩個大小相等的列表,並且希望按位置進行匹配,即需要並行迭代它們。
這樣做:
List<Integer> insIds = /*...*/
List<Abc> abcList = abcController.findAbcsByInsIds(insIds);
Map<Integer, Integer> insIdToAbcId = new HashMap<>(insIds.size() * 4 / 3 + 1);
Iterator<Integer> insIter = insIds.iterator();
Iterator<Abc> abcIter = abcList.iterator();
while (insIter.hasNext())
insIdToAbcId.put(insIter.next(), abcIter.next().getAbcId());
即使列表為LinkedList
,此代碼也可以很好地執行。
HashMap
已預先分配為適當的大小,因此消除了調整大小的需要,從而避免了需要重新HashMap
情況,即提高性能。
Map< Integer, Integer > insIdToAbcId = findAbcsByInsIds( insIds )
.stream( )
.collect( HashMap::new, ( map, abc ) -> map.put( insIds.get( map.size( ) ), abc.getAbcId( ) ), ( a, b ) -> {} );
對於每個版本,解決合同中有關第三個參數的問題
Map< Integer, Integer > map = new HashMap<>( );
findAbcsByInsIds( insIds )
.forEach( (abc) -> map.put( insIds.get( map.size( ) ), abc.getAbcId( ) ));
這實際上更簡單,甚至不需要收集器,甚至收集器的輔助流。 但是關於collect方法,可以使用不受支持的異常來確保永遠不會調用該異常,如果下划線jre的實現細節發生更改,則在不知情的情況下也不會更改。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.