简体   繁体   English

从列表映射java8中获取单个键的所有值

[英]Get all the values of single key from the list map java8

I have the list as follows: 我的清单如下:

List<Map<String,Object>> mapList=new ArrayList<>();
Map<String,Object> mapObject=new HashMap<String,Object>();
mapObject.put("No",1);
mapObject.put("Name","test");
mapList.add(mapObject);
Map<String,Object> mapObject1=new HashMap<String,Object>();
mapObject1.put("No",2);
mapObject1.put("Name","test");
mapList.add(mapObject1);

and so on...

Now I want to get all the values of the key "No" as a string seperated by comma as follows: 现在,我想获取键“ No”的所有值作为用逗号分隔的字符串,如下所示:

String noList="1,2,3"

Can anyone please suggest me what may best way to do it. 任何人都可以建议我什么是最好的方法。 I know we can do it by looping but instead of looping is any other ways to do it. 我知道我们可以通过循环来做到这一点,但是除了循环之外,其他任何方式也可以做到这一点。

Explanations inline! 内联说明!

mapList.stream()                       // stream over the list
    .map(m -> m.get("No"))             // try to get the key "No"
    .filter(Objects::nonNull)          // filter any null values in case it wasn't present
    .map(Object::toString)             // call toString for each object
    .collect(Collectors.joining(",")); // join the values

Simply map the list: 只需映射列表:

String list = mapList.stream()
    .filter(x -> x.containsKey("No")) // get only the maps that has the key
    .map(x -> x.get("No").toString()) // every map will be transformed like this
   .collect(Collectors.joining(",")); // joins all the elements with ","
System.out.println(list);

The use of HashMap<String, Object> suggests that it might be better to create a new class for this data. HashMap<String, Object>表明为该数据创建一个新类可能更好。 Have you considered this possibility before? 您之前考虑过这种可能性吗?

You can loop like this: 您可以像这样循环:

List<String> noList = new ArrayList<>(mapList.size());
for (Map<String,Object> m : mapList) {
    Optional.ofNullable(m.get("No")) // get value mapped to "No" or empty Optional
        .map(Object::toString)
        .ifPresent(noList::add); // if not empty, add to list
}
System.out.println(String.join(",", noList));

or internally (the officially preferred version IIRC): 或内部(官方首选版本IIRC):

List<String> noList = new ArrayList<>(mapList.size());
mapList.forEach(m -> 
    Optional.ofNullable(m.get("No")).map(Object::toString).ifPresent(noList::add));
System.out.println(String.join(",", noList));

Now that I think of it, it's shorter than the Stream version. 现在我想到了,它比Stream版本短。

Answered a pretty similar question 30 minutes ago. 30分钟前回答了一个非常类似的问题。

You are using repeated keys. 您正在使用重复键。 This makes it look like you don't need maps, but a class with the attributes "No", "Name", etc. If you've this class you can just iterate your instances on the list and concatenating to a String. 这使您看起来好像不需要映射,而是一个具有属性“ No”,“ Name”等的类。如果您具有此类,则可以仅在列表上迭代实例并串联为String。

If no matter what you want to have your maps, simply get the values of the "No" key, but note that this is a wrong practise and you should be probably using a class instead of maps: 如果无论您想拥有什么地图,只需获取“ No”键的值即可,但是请注意,这是错误的做法,您可能应该使用类而不是地图:

String res = "";

for(int i = 0; i < mapList.size(); i++) {
    Map<String,Object> map = mapList.get(i);
    res.concat(map.get("No"));
    if(i != mapList.size() - 1)
        res.concat(",");
}

PS: If you are going with the bad solution practise, use the stream alternatives in the other answers if your knowledge of stream is enough to understand them. PS:如果您使用的是不好的解决方案,那么,如果您对流的了解足以理解它们,请在其他答案中使用流替代方案。

Try this out, 试试看

String concatValues = mapList.stream().map(map -> String.valueOf(map.get("No")))
        .collect(Collectors.joining(","));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM