我遇到了很奇怪的情况,也许有人有同样的情况,可以帮忙解决这个问题:
public class TestMap {
private Long firstId;
private Long secondId;
}
我创建了 TestMap.class
列表并设置值:
List<TestMap> mapRecords = new ArrayList<>();
mapRecords.add(new TestMap(1L, null));
mapRecords.add(new TestMap(2L, null));
mapRecords.add(new TestMap(3L, null));
Map<Long, Long> firstMap = new HashMap<>();
firstMap.put(11L, 1L);
firstMap.put(22L, 2L);
firstMap.put(33L, 3L);
Map<Long, Long> secondMap = new HashMap<>();
secondMap.put(11L,111L);
secondMap.put(22L,222L);
Map<Long, Long> finalMap = secondMap.entrySet().stream()
.filter(mapFilter -> firstMap.containsKey(mapFilter.getKey()))
.collect(Collectors.toMap(mapFilter -> firstMap.get(mapFilter.getKey()), Map.Entry::getValue));
mapRecords.stream().forEach(contractParametersRecord ->
finalMap.entrySet().stream()
.forEach(some -> {
if (some.getKey().equals(contractParametersRecord.getFirstId())) {
contractParametersRecord.setSecondId(some.getValue());
}
}));
我有两个具有相同键但不同值的映射,其中第一个映射的值对应于列表mapRecords 的第一个值
firstId
。我需要制作两个映射之一,其中第一个映射的值成为键,第二个映射的值成为最后设置到 mapRecords 列表的值。我已经完成了所有这些,但如果您注意到第一个地图有三个值。当不匹配时,我需要两个地图之一来抛出错误。
如何使用流来完成此操作?
或者我只使用 try/cach 块?
首先,检查第一个和第二个映射是否具有相同的键,如果不相同则失败:
if (!firstMap.keySet().equals(secondMap.keySet())) {
throw new IllegalArgumentException();
}
然后您可以通过将第二个映射中的键替换为第一个映射中的相应值来继续构建映射;不需要过滤器,因为您已经验证了密钥是等效的:
Map<Long, Long> finalMap = secondMap.entrySet().stream()
.collect(Collectors.toMap(e -> firstMap.get(e.getKey()), Map.Entry::getValue));
最后,不要在另一个循环中低效地迭代最终映射的条目(大约 O(n2) 操作),只需将其作为映射进行访问:
for (TestMap contractParametersRecord : mapRecords) {
Long val = finalMap.get(contractParametersRecord.getFirstId());
if (val != null) {
contractParametersRecord.setSecondId(val);
}
}
我认为这会很好:
Map<Long, Long> finalMap = firstMap.entrySet().stream()
.map(c -> secondMap.entrySet().stream()
.filter(entry -> entry.getKey().equals(c.getKey()))
.findFirst()
.orElseThrow(() -> new IllegalArgumentException(String.format("Error: ID %s was not found", c.getKey() ))))
.collect(Collectors.toMap(mapFilter -> firstMap.get(mapFilter.getKey()), Map.Entry::getValue));
如果有更好的方法可以有人写吗? :)