Как конвертировать Stream> к карте Ява 8 - PullRequest
0 голосов
/ 13 декабря 2018

Здесь я публикую пример структуры данных

У меня есть список List<Result> resultsList;

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

Теперь я хотел бы просмотреть этот список и получить карту.

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

Возвращает Stream<Map<String,Integer>>, но мне нужно только Map<String,Integer>.

Как получить его, используя потоки Java 8?

Обновление:

Как geneqew упомянуто

Так выглядит моя структура данных

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

Я хотел бы получить одну карту на основе name.

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

Ответы [ 4 ]

0 голосов
/ 13 декабря 2018

Поскольку вам нужна только карта, соответствующая названию результатов, тогда:

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

, если у вас есть пример содержимого:

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

Немного пояснений, вы получилипоток, потому что последняя операция в вашем потоке является картой;предполагая, что в вашем списке возможно иметь более 1 результата с одним и тем же именем, findFirst вернет первое совпадение, если найдено, в противном случае возвращается пустой необязательный аргумент;Наконец, orElse для получения завершения потока, предоставляя нулевое значение при пустом совпадении.

0 голосов
/ 13 декабря 2018

, если вы ищете только один элемент:

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

, если фильтр может соответствовать более чем одному элементу, тогда вам нужно будет сплющить toMap it:

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

если могут быть дубликаты, используйте функцию слияния для разрешения коллизий:

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));
0 голосов
/ 13 декабря 2018

Итак, я хочу объяснить, почему вы получаете поток, а не карту.Причина этого в том, что в начале у вас есть List с Result объектами, которые вы фильтруете по некоторым критериям (в вашем случае "xxx".equals(result.getName())).

Теперь вы можете иметь нулевой результатодин или несколько элементов, которые будут соответствовать этому критерию!Java не знает, сколько элементов пройдет во время компиляции, и поэтому вы получаете Stream.

Представьте себе ситуацию, когда у вас есть два объекта Result с одинаковым именем «xxx», тогда у вас будет двакарты.Вопрос в том, что вы хотите сделать?Если вы получите только одну из карт, вы потеряете информацию.Если вы хотите получить их все, попробуйте что-то вроде этого:

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

Теперь в этом listWithResultMaps вы можете обработать все карты, которые у вас есть в результате вашего фильтра.

Удачи!

0 голосов
/ 13 декабря 2018

Поскольку вы хотите вернуть карту результатов первого элемента Result, чтобы пройти фильтр, вы можете получить его с помощью findFirst():

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

. Вы можете извлечь Map изOptional таким образом:

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