我正在尝试使用List<Object>
将Map<String, List>
转换为Streams
,
public class User{
String name;
String age;
String org;
}
我有List<Users>
,需要收集到Map<String, Object> m
,
m.put("names", List of names,);
m.put("age", List of age);
m.put("org", List of org);
在命名查询中使用 - &gt;例如:select * from table ... where names in (:names) and age in (:age) and org in (:org)
截至目前我正在做
List<String> names = userList.stream().map(User::getName).collect(Collectors.toList());
List<String> age= userList.stream().map(User::getAge).collect(Collectors.toList());
List<String> org= userList.stream().map(User::getName).collect(Collectors.toList());
如何只在流式传输到列表一次时收集所有值?
答案 0 :(得分:8)
我相信这样的事情应该有效:
let s = "\n54766392632990,178.32.243.13,wfsdsfsdfs23432,\n54766393632990,178.32.243.13,"
s = s.split("\n");
let array = [];
for(let i=0;i<s.length;i++) {
let v = s[i].split(",178.32.243.13,");
for(let j=0;j<v.length;j++) {
if(!isNaN(parseInt(v[j]))) {
array.push(v[j]);
}
}
}
console.log(array);
它将每个Map<String,List<String>> map =
userList.stream()
.flatMap(user -> {
Map<String,String> um = new HashMap<>();
um.put("names",user.getName());
um.put("age",user.getAge());
um.put("org",user.getOrg());
return um.entrySet().stream();
}) // produces a Stream<Map.Entry<String,String>>
.collect(Collectors.groupingBy(Map.Entry::getKey,
Collectors.mapping(Map.Entry::getValue,
Collectors.toList())));
转换为User
(包含由所需键索引的3个必需属性),然后按键对所有用户地图的条目进行分组。
编辑:
这是另一种直接创建Map<String,String>
而非创建小Map.Entry
的替代方案,因此它应该更有效:
HashMap
答案 1 :(得分:6)
Eran's showed you如何使用流来完成此任务。正如你可以看到的那样,它非常难看。
如果你的程序版本的问题是代码重复的数量,除了流之外还有其他方法可以用来解决这个问题。
我会将集合重构为自己的方法:
private static List<String> getProperty(List<User> users, Function<User, String> getter) {
return users.stream().map(getter).collect(Collectors.toList());
}
Map<String,List<String>> map = new HashMap<>();
map.put("names", getProperty(userList, User::getName));
map.put("age", getProperty(userList, User::getAge));
map.put("org", getProperty(userList, User::getOrg));
答案 2 :(得分:1)
@Eran和@Michael都提供了一个很好的解决方案,我想用通用方法解决你的问题:
public static void main(String[] args) throws IllegalArgumentException, IllegalAccessException {
List<User> listUsers = ...
//Create a List which hold name of field and its value
List<Map<String, Object>> listMapping = new ArrayList<>();
for (User user : listUsers) {
listMapping.add(fieldNameValue(user));
}
//Here group by the name of the field
Map<String, List<Object>> result = listMapping.stream()
.flatMap(a -> a.entrySet().stream())
.collect(Collectors.groupingBy(Map.Entry::getKey,
Collectors.mapping(Map.Entry::getValue, Collectors.toList())));
}
//This method return a Map which hold names of attributes and its values.
static Map<String, Object> fieldNameValue(Object obj) throws IllegalArgumentException, IllegalAccessException {
Map<String, Object> mapping = new HashMap<>();
for (Field field : obj.getClass().getDeclaredFields()) {
field.setAccessible(true);
mapping.put(field.getName(), field.get(obj));
}
return mapping;
}
在此解决方案中,您不关心该类型的字段数。
答案 3 :(得分:0)
试试这个。 用于将列表值和键从列表中分离的颜色bean。
List<Color> colors = new ArrayList<Color>();
colors.add(new Color("RED", "#FF0000"));
colors.add(new Color("BLUE", "#0000FF"));
colors.add(new Color("GREEN", "#008000"));
// construct key-value pairs from name and code fields of Color
Map<String, String> map = colors.stream()
.collect(Collectors.toMap(Color::getName,
Color::getCode));