简体   繁体   English

java-stream,map,与对象无关的键

[英]java-stream, map, keys not related to object

So I have a list of integer that is insIds, from this I can get a list of ABCs, I want to map them to an entry in map (notice that we can not getInsId from Abc.getIns) 所以我有一个insIds的整数列表,从中我可以得到一个ABC列表,我想将它们映射到map中的一个条目(注意,我们不能从Abc.getIns中获取getInsId)

This is what I want it to be: (but since we do not have getInsId we are not able to write this way) 这就是我想要的:(但是由于我们没有 getInsId,所以我们无法以这种方式编写)

Map<Integer, Integer> insIdToAbcId = abcController
          .findAbcsByInsIds(insIds)
          .stream()
          .collect(Collectors.toMap(Abc::getInsId,
            Abc::getAbcId));

I am not sure how to write it in order to have the mapping relationship I want. 我不确定如何编写它以具有所需的映射关系。

Known list of integer: insIds 已知整数列表: insIds

Known function that will take insIds and return list: 已知函数将采用insIds并返回列表:

abcController.findAbcsByInsIds(insIds)

And then is what I am not sure about: how to map insId to AbcId 然后是我不确定的问题:如何将insId映射到AbcId

(expect output: Map<Integer, Integer> insIdToAbcId ) (预期输出: Map<Integer, Integer> insIdToAbcId

If there's an ordered one-to-one relationship between the items in insIds and the result of findAbcsByInsIds() , you can join the lists by index: 如果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()));

This is a prime example of a problem where Stream is not the right solution. 这是Stream不是正确解决方案的问题的主要示例。

After the findAbcsByInsIds() call, you have two lists of equal size, and you want to match them, by position, ie you need to parallel iterate them. findAbcsByInsIds()调用之后,您将获得两个大小相等的列表,并且希望按位置进行匹配,即需要并行迭代它们。

So do that: 这样做:

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());

This code will perform well, even if lists are LinkedList . 即使列表为LinkedList ,此代码也可以很好地执行。
The HashMap was preallocated to appropriate size, so resizing is eliminated, preventing need to rehash, ie for better performance. HashMap已预先分配为适当的大小,因此消除了调整大小的需要,从而避免了需要重新HashMap情况,即提高性能。

Map< Integer, Integer > insIdToAbcId = findAbcsByInsIds( insIds )
            .stream( )
            .collect( HashMap::new, ( map, abc ) -> map.put( insIds.get( map.size( ) ), abc.getAbcId( ) ), ( a, b ) -> {} );

For each version to address the contract concerns about the third parameter 对于每个版本,解决合同中有关第三个参数的问题

    Map< Integer, Integer > map = new HashMap<>(  );
    findAbcsByInsIds( insIds )
            .forEach( (abc) -> map.put( insIds.get( map.size( ) ), abc.getAbcId( ) ));

This is actually simpler and there in no need for boxing, auxiliary streams of even a collector. 这实际上更简单,甚至不需要收集器,甚至收集器的辅助流。 But about the collect method one could use an unsupported exception to make sure it is never called, should the implementation details of the underline jre change, it would not change without one's knowledge. 但是关于collect方法,可以使用不受支持的异常来确保永远不会调用该异常,如果下划线jre的实现细节发生更改,则在不知情的情况下也不会更改。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM