【发布时间】:2016-08-15 13:40:57
【问题描述】:
假设我有一个这样的多地图:
MiddleName -> null
EmailAddress -> Toni@mymail.com, Mary@hermail.com, Paul@hismail.com
FirstName -> Toni, Mary, Paul
LastName -> Barry, null ,White
Id -> null
请注意每个“值”条目如何可以完全为空,或者包含与具有更多条目(我不知道是哪一个)相同数量的值,即使其中一些为空。
我希望它“转置”到这样的地图列表中:
MiddleName -> null
EmailAddress -> Toni@mymail.com
FirstName -> Toni
LastName -> Barry
Id -> null
MiddleName -> null
EmailAddress -> Mary@hermail
FirstName -> John
LastName -> null
Id -> null
MiddleName -> null
EmailAddress -> Paul@hismail.com
FirstName -> Paul
LastName -> White
Id -> null
我正在尝试使用 java8 流来执行此操作,但也可以以“旧”样式执行此操作。
搜索 stackoverflow 我发现了一个类似的问题 [1] 和其他一些相关的 [2,3,4],它们给了我一些想法,但没有完全适应。
现在,我确实实现了自己的解决方案,可以按我的意愿工作,但坦率地说,这可能是我多年来编写的最丑陋的代码......
List result = (...)
map.forEach(h -> {
MultiValueMap<String, String> m = new LinkedMultiValueMap();
h.entrySet().stream().forEach(e -> {
String[] ss = e.getValue() == null ? null : e.getValue().toString().split(",");
if (ss != null) {
Arrays.asList(ss).stream().forEach(s -> m.add(e.getKey(), s));
}
});
if (m.size() > 0) {
int x = m.values().stream().max((o1, o2) -> o1.size() - o2.size()).get().size();
for (int i = 0; i < x; i++) {
Map<String, String> n = (Map) h.clone();
Iterator<Map.Entry<String, String>> it = n.entrySet().iterator();
while( it.hasNext()){
Map.Entry<String, String> e = it.next();
List<String> ss = m.get(e.getKey());
if(ss!=null) {
e.setValue(ss.get(i));
}
}
result.add(n);
}
}
});
第一遍只是将字符串拆分为一个数组,因为它最初是一个逗号分隔的字符串。然后我找到任何值中的最大元素数,我将条目中的所有值循环该次数,并为每个值创建一个带有结果的映射。坦率地说,我上周五写了这段代码,我还不能正确阅读它......
所以,起初这是一件简单的事情,但我最终陷入了困境,有没有更好的方法来做到这一点?
提前致谢。
[1]Java8 streams : Transpose map with values as list
[2]reversing keys/values - create new instance of HashMap
【问题讨论】:
标签: java java-8 java-stream