简体   繁体   中英

How to convert Stream<Map<Integer, String>> to map java 8

Here I am posting sample datastructure

I have a list List<Result> resultsList;

class Result { 
    String name; 
    Map<String,Integer> resultMap; 
}

Now I would like to stream through this list and get the map.

resultList.stream().filter(result->"xxx".equals(result.getName()))
                   .map(result->result.getResultMap);

It returns Stream<Map<String,Integer>> but I need only Map<String,Integer> .

How to get it using java 8 streams?

Update:

As geneqew mentioned

This is how my datastructure looks

List<Result> resultsList;

Map<String, Integer> map1 = new HashMap<>();
map1.put("m1", 1);
Map<String, Integer> map2 = new HashMap<>();
map2.put("m2", 2);
Map<String, Integer> map3 = new HashMap<>();
map3.put("m3", 3);

results = Arrays.asList(
        new Result("r1", map1),
        new Result("r2", map2),
        new Result("r3", map3)
);

I would like to retrieve single map based on name .

for (Result result: resultsList)
{
   if ('xxx'.equals(result.getName())
   {
      return result.getResultMap();
   }
} 

Since you want to return the result map of the first Result element to pass your filter, you can obtain it with findFirst() :

Optional<Map<String,Integer>> resultMap = 
    resultList.stream()
              .filter(result->"xxx".equals(result.getName()))
              .map(Result::getResultMap)
              .findFirst();

You can extract the Map from the Optional this way:

Map<String,Integer> resultMap = 
    resultList.stream()
              .filter(result->"xxx".equals(result.getName()))
              .map(Result::getResultMap)
              .findFirst()
              .orElse(null);

if you're only looking for one item:

resultList.stream()
          .filter(result -> "xxx".equals(result.getName()))
          .map(Result::getResultMap)
          .findAny();

if the filter could match more than one item then you'll need to flatten then toMap it:

resultList.stream()
          .filter(result-> "xxx".equals(result.getName()))
          .flatMap(result -> result.getResultMap().entrySet().stream())
          .collect(toMap(Map.Entry::getKey, Map.Entry::getValue));

if there can be duplicates then use the merge function to resolve collisions:

resultList.stream()
          .filter(result -> "xxx".equals(result.getName()))
          .flatMap(result -> result.getResultMap().entrySet().stream())
          .collect(toMap(Map.Entry::getKey, Map.Entry::getValue, (l, r) -> l));

Since you only wanted the map that matches the results' name then:

 results.stream()
               .filter(r-> r.getName().equals("r2"))
               .map(r-> r.getResultMap())
               .findFirst()
               .orElse(null); 

given you have a sample content of:

List<Result> results;

Map<String, Integer> map1 = new HashMap<>();
map1.put("m1", 1);
Map<String, Integer> map2 = new HashMap<>();
map2.put("m2", 2);
Map<String, Integer> map3 = new HashMap<>();
map3.put("m3", 3);

results = Arrays.asList(
        new Result("r1", map1),
        new Result("r2", map2),
        new Result("r3", map3)
);

A bit of explanation, you got a stream because the last operation in your stream is a map; assuming in your list its possible to have more than 1 result with the same name, findFirst will return the first match if found otherwise an empty optional is returned; Finally orElse to get terminate the stream, providing a null value on empty match.

So I want to explain why you receive stream and not a map. The reason of this is because in the beginning you have List with Result objects that you filter by some criteria (in your case "xxx".equals(result.getName()) ).

Imagine situation that you have two Result objects that have the same name 'xxx' then you will have two maps. The question is what you want to do? If you get only one of the maps you will loose information. If you want to get all of them, please try something like this:

        List<Map<String,Integer>> listWithResultMaps = resultList.stream()
                                                   .filter(result->"xxx".equals(result.getName()))
                                                   .map(result->result.getResultMap())
                                                   .collect(Collectors.toList());

Now in this listWithResultMaps you can process all maps that you have as result of your filter.

Good Luck!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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