Java 8要映射的对象列表<string,list =“”>值

时间:2018-05-15 10:41:10

标签: java java-8

我正在尝试使用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());

如何只在流式传输到列表一次时收集所有值?

4 个答案:

答案 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));