如何将Stream <map <integer,string =“” >>转换为Map Java 8

时间:2018-12-13 07:33:52

标签: java java-8 java-stream

我在这里发布示例数据结构

我有一个列表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 :(得分:4)

由于您要返回第一个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);

答案 1 :(得分:2)

如果您只寻找一项:

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

如果过滤器可以匹配多个项目,则需要将其展平,然后toMap

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

答案 2 :(得分:1)

由于您只想要与结果名称匹配的地图,所以:

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

有点解释,您得到了一个流,因为流中的最后一个操作是地图;假设您的列表中可能有多个具有相同名称的结果,则findFirst将返回第一个匹配项(如果找到),否则返回一个空的可选值;最终orElse终止流,在空匹配时提供空值。

答案 3 :(得分:0)

所以我想解释一下为什么您收到流而不是地图。之所以这样,是因为在开始时,您有server = function(input, output, session){ day1 = reactive({ req(input$Home, input$Season) appliance[appliance$Home %in% input$Home & appliance$Season %in% input$Season,] }) output$day1 = DT::renderDataTable({ req(day1(), input$Day1C) x <- day1() x$Run <- ifelse(x$Timein24 == input$Day1C, 1, 0) x }) } 带有List个对象,这些对象可以通过某些条件(在您的情况下为Result)进行过滤。

现在,结果为零,一个或多个将通过此条件的元素! Java不知道在编译时会传递多少个元素,这就是为什么要获得Stream的原因。

想象一下,假设您有两个具有相同名称“ xxx”的Result对象,那么您将有两个映射。问题是你想做什么?如果仅获得其中一张地图,则会丢失信息。如果要全部获取,请尝试以下操作:

"xxx".equals(result.getName())

现在,在此 List<Map<String,Integer>> listWithResultMaps = resultList.stream() .filter(result->"xxx".equals(result.getName())) .map(result->result.getResultMap()) .collect(Collectors.toList()); 中,您可以处理作为过滤器结果的所有地图。

祝你好运!