我有以下收藏:
Map<String, Map<SomeEnum, Long>> map = ...
以下是示例数据:
{"Foo": {
SomeEnum.BAR1: 1,
SomeEnum.BAR2: 2,
SomeEnum.BAR3: 3
},
"two": {...}
由于我知道所有枚举,因此我想将其转换为POJO列表。对象的定义如下:
class SomeClass {
String name;
long bar1Value;
long bar2Value;
long bar3Value;
}
我尝试了不同的解决方案,例如在映射内部进行映射:
map.entrySet().stream()
.map(e -> e.getValue().entrySet().stream().map(innerEntry -> {
long bar1 = 0;
long bar2 = 0;
long bar3 = 0;
if(innerEntry.getKey().equals(SomeEnum.BAR1)) bar1 = innerEntry.getValue();
if(innerEntry.getKey().equals(SomeEnum.BAR2)) bar2 = innerEntry.getValue();
if(innerEntry.getKey().equals(SomeEnum.BAR3)) bar3 = innerEntry.getValue();
return new SomeClass(e.getKey(), bar1, bar2, bar3);
}).collect(toList()).collect(toList());
不幸的是,我得到的是List<List<SomeClass>>
。
还有其他更优雅的方式来处理此问题吗?
答案 0 :(得分:5)
这对您有用吗?
它需要目标类的构造函数,但仅获取值并创建实例。然后将它们收集到列表中。
List<SomeClass> list = map.entrySet().stream()
.map(e -> new SomeClass(e.getKey(),
e.getValue().get(SomeEnum.BAR1),
e.getValue().get(SomeEnum.BAR2),
e.getValue().get(SomeEnum.BAR3)))
.collect(Collectors.toList());
带有构造函数的类
class SomeClass {
String name;
long bar1Value;
long bar2Value;
long bar3Value;
public SomeClass(String name, long bar1Value, long bar2Value,
long bar3Value) {
this.name = name;
this.bar1Value = bar1Value;
this.bar2Value = bar2Value;
this.bar3Value = bar3Value;
}
}
答案 1 :(得分:4)
您可以使用实用程序从内部映射中创建df$species <- sub(".*\\*{3}retired\\*{3}use\\s+", "", df$species)
来简化整个任务:
SomeClass
然后您的映射就像-
private SomeClass createSomeClass(String name, Map<SomeEnum, Long> innerMap) {
return SomeClass.builder()
.name(name)
.bar1Value(innerMap.getOrDefault(SomeEnum.BAR1, 0L))
.bar2Value(innerMap.getOrDefault(SomeEnum.BAR2, 0L))
.bar3Value(innerMap.getOrDefault(SomeEnum.BAR3, 0L))
.build();
}
答案 2 :(得分:2)
将map
更改为flatMap
并删除第一个toList()
List<SomeClass> ss = map.entrySet().stream()
.flatMap(e -> e.getValue().entrySet().stream().map(innerEntry -> {
long bar1 = 0;
long bar2 = 0;
long bar3 = 0;
if(innerEntry.getKey().equals(SomeEnum.BAR1)) bar1 = innerEntry.getValue();
if(innerEntry.getKey().equals(SomeEnum.BAR2)) bar2 = innerEntry.getValue();
if(innerEntry.getKey().equals(SomeEnum.BAR3)) bar3 = innerEntry.getValue();
return new SomeClass(e.getKey(), bar1, bar2, bar3);
})).collect(Collectors.toList());
答案 3 :(得分:1)
您必须这样做:
首先添加一种方法来为每个枚举值设置特定的长整数,如下所示:
class SomeClass {
String name;
long bar1Value;
long bar2Value;
long bar3Value;
//获取器和设置器
public void setByEnum(SomeEnum t, Long value) {
switch (t) {
case BAR1:
this.setBar1Value(value);
break;
case BAR2:
this.setBar2Value(value);
break;
case BAR3:
this.setBar3Value(value);
break;
}
}
}
然后,您需要使地图循环播放,如下所示:
List<SomeClass> list = new ArrayList<>();
map.forEach((name,values)->{
SomeClass s = new SomeClass();
s.setName(name);
values.forEach((t,value)->{
s.setByEnum(t, value);
});
list.add(s);
});
答案 4 :(得分:0)
那这样的事情呢?
ArrayList<Integer> keyList = new ArrayList<Integer>(map.keySet());
for(int i=0; i<keyList.size(); i++){
Map innermap = map.get(keyList.get(i));
SomeClass obj = new SomeClass(keyList.get(i),innermap.get('bar1'),innermap.get('bar2'),innermap.get('bar3');
}