我有一个List<Map<String, Object>>
包含以下数据,显示为json以便于阅读:
data1 = [ {
"siteId" : 1,
"siteName" : "Site 1",
"member" : "John Doe",
"age" : 20
}, {
"siteId" : 1,
"siteName" : "Site 1",
"member" : "James Doe",
"age" : 30
}, {
"siteId" : 2,
"siteName" : "Site 2",
"member" : "Jane Doe",
"age" : 40
}, {
"siteId" : 2,
"siteName" : "Site 2",
"member" : "Judy Doe",
"age" : 50
} /* etc ... */ ]
我需要将其转换为:
data2 = [ {
"siteId" : 1,
"siteName" : "Site 1",
"values" : [ {
"siteId" : 1,
"siteName" : "Site 1",
"member" : "John Doe",
"age" : 20
}, {
"siteId" : 1,
"siteName" : "Site 1",
"member" : "James Doe",
"age" : 30
} ]
}, {
"siteId" : 2,
"siteName" : "Site 2",
"values" : [ {
"siteId" : 2,
"siteName" : "Site 2",
"member" : "Jane Doe",
"age" : 40
}, {
"siteId" : 2,
"siteName" : "Site 2",
"member" : "Judy Doe",
"age" : 50
} ]
} ]
如何以一种有效的(Java8-ish)方式避免多个嵌套循环呢?
修改
这是我迄今为止提出的最好的方法:
List<Map<String, Object>> data1 = service.getData1();
List<Map<String, Object>> data2 = new ArrayList<>();
Map<String, Object> t2 = new HashMap<String, Object>();
data1.forEach(item -> {
String id = (String) item.get("siteId");
if (!t2.containsKey(id)) {
t2.put(id, item.get("siteName"));
}
});
t2.forEach((k, v) -> {
Map<String, Object> t3 = new HashMap<String, Object>();
t3.put("siteId", k);
t3.put("siteName", v);
t3.put("values", r.stream().filter(line -> ((String) line.get("siteId")).equals(k)).collect(Collectors.toList()));
data2.add(t3);
});
修改2
在咨询Maurice Perry的答案后,结果证明这是最佳解决方案:
public List<Map<String, Object>> transformListToGrouped2(final List<Map<String, Object>> r, final String key1, final String key2) {
List<Map<String, Object>> values = new ArrayList<>();
final List<Map<String, Object>> data2 = new ArrayList<>();
Map<String, Object> prev = null;
for (final Map<String, Object> cur : r) {
if (prev == null || !prev.get(key1).equals(cur.get(key1))) {
final Map<String, Object> obj = new HashMap<>();
values = new ArrayList<>();
obj.put(key1, cur.get(key1));
obj.put(key2, cur.get(key2));
obj.put("values", values);
data2.add(obj);
}
values.add(cur);
prev = cur;
}
return data2;
}
答案 0 :(得分:1)
这应该这样做:
List<Map<String, Object>> values = null;
Map<String, Object> prev = null;
for (Map<String, Object> cur: data1) {
if (prev == null || !prev.get("siteId").equals(cur.get("siteId"))) {
Map<String,Object> obj = new HashMap<>();
values = new ArrayList<>();
obj.put("siteId", cur.get("siteId"));
obj.put("siteName", cur.get("siteName"));
obj.put("values", values);
data2.add(obj);
}
values.add(cur);
prev = cur;
}
答案 1 :(得分:0)
以下是更多Java-8尝试方法 -
class SiteInfo {
int siteId
String siteName
}
class VisitInfo {
int siteId
String siteName
String member
int age
getSiteInfo {
return new SiteInfo(siteId, siteName)
}
}
class GroupedVisitInfo {
int siteId
String siteName
List[VisitInfo] userVisits
}
// code
Map <SiteInfo, List<VisitInfo>> groupedVisitInfo = userVisitdata.stream().collect(groupingBy(VisitInfo::getSiteInfo));
尝试一下,让我知道你的意见。