使用Lambda查找平均值(双精度存储为字符串)

使用Lambda查找平均值(双精度存储为字符串),lambda,average,java-8,Lambda,Average,Java 8,我有一个如下格式的对象 Map<String, List<ObjectDTO>> mapOfIndicators = new HashMap<>(); 我试图计算newIndex值的平均值,这基本上是我无法做到的,因为getNewIndex是字符串,并且可能有空字符串(值)。我无法将空值转换为0,因为newIndex中将有0个值 有没有更简单的方法来计算平均值 例如 mapOfIndicators=newHashMap(); List _tempValue=

我有一个如下格式的对象

Map<String, List<ObjectDTO>> mapOfIndicators = new HashMap<>();
我试图计算newIndex值的平均值,这基本上是我无法做到的,因为getNewIndex是字符串,并且可能有空字符串(值)。我无法将空值转换为0,因为newIndex中将有0个值

有没有更简单的方法来计算平均值

例如

mapOfIndicators=newHashMap();
List _tempValue=newArrayList();
IndicatorTableDTO _iTDTO=新的IndicatorTableDTO(“iName”、“dName”、“countryName1”、2012、“1.00”);
_tempValue.add(_iTDTO);
_iTDTO=新指标TableDTO(“iName”、“dName”、“countryName2”、2012年“);
_tempValue.add(_iTDTO);
_iTDTO=新指标表DTO(“iName”、“dName”、“countryName3”,2012年,“0.02”);
_tempValue.add(_iTDTO);
_iTDTO=新指标TableDTO(“iName”、“dName”、“countryName4”、2012年、-0.25”);
_tempValue.add(_iTDTO);
_iTDTO=新指标表DTO(“iName”、“dName”、“countryName5”、2012年,“0.10”);
_tempValue.add(_iTDTO);
mapOfIndicators.put(“Test1”,_tempValue);
_iTDTO=新指标表DTO(“iName”、“dName”、“countryName1”、2012、“0.10”);
_tempValue.add(_iTDTO);
_iTDTO=新的指示符TableDTO(“iName”、“dName”、“countryName2”、2012、”、”、”);
_tempValue.add(_iTDTO);
_iTDTO=新的指示符TableDTO(“iName”、“dName”、“countryName3”、2012、”、”、”);
_tempValue.add(_iTDTO);
_iTDTO=新指标TabledTo(“iName”、“dName”、“countryName4”、2012、“0.25”和“,”);
_tempValue.add(_iTDTO);
_iTDTO=新指标TabledTo(“iName”、“dName”、“countryName5”、2012、“1.10”和“,”);
_tempValue.add(_iTDTO);
mapOfIndicators.put(“Test2”,_tempValue);

更新01:我们可以跳过空字符串/空值;平均值将按countryName计算,因此我希望找到同一contryName的新索引的平均值,并最终能够得到一个映射作为最终结果。

如果您希望计算值的平均值,并将其收集到一个与源映射具有相同键的
映射中,您可以通过以下方式进行:

Map<String, Double> averages=mapOfIndicators.entrySet().stream()
    .collect(Collectors.toMap(Map.Entry::getKey, e->e.getValue().stream()
       .map(ObjectDTO::getNewIndex).filter(str->!str.isEmpty())
       .mapToDouble(Double::parseDouble).average().orElse(Double.NaN)));

好吧,这与第一次猜测时你的意图是正确的相似…

未经测试,但应该可以做到这一点(或者至少可以引导你找到解决方案):

Map averageByCountryName=
map.values()
.stream()
.flatMap(列表->列表.stream())
.filter(objectDTO->!objectDTO.getNewIndex().isEmpty())
.collect(收集器.groupingBy(
ObjectDTO::getCountry,
平均双倍(
objectDTO->Double.parseDouble(objectDTO.getNewIndex());

您应该包括您的传统计算方法,以使您的意图更加清晰。您希望每个地图条目的平均值还是整个地图的平均值,您希望将空字符串视为0还是跳过它们(这是不同的…)?有一个简单的方法,只要你定义了平均值应该是多少。如果你不知道字符串为空时整数值应该是多少,我们也不能。@Holger,在bottom@JB-Nizet更新了question@Vivek:那么
countryName
已经是地图的键了吗?如果我之前的注释把你弄糊涂了,很抱歉。ObjectDTO具有countryName,而不是我们试图从中读取的映射,如果您看到上面的示例,则键为“Test1”和“Test2”。我们需要使用ObjectDTO.getCountryName()创建一个新的may作为列表中所有国家/地区名称的关键和平均值;来自Test1和Test2。谢谢,您的解决方案看起来也很优雅。这里有一个简单的问题,您在这里添加的过滤器正在检查它是否为非空,是否有一种方法可以忽略整个国家/地区映射,即使其中一个是新的,该国家/地区的索引是否为空?@Vivek:这不是问题“快速提问”是一个全新的问题。提出新问题不是评论的目的。@Vivek:你可以提出一个新问题,你知道…
mapOfIndicators = new HashMap<>();
List<IndicatorTableDTO> _tempValue = new ArrayList();
IndicatorTableDTO _iTDTO = new IndicatorTableDTO("iName", "dName", "countryName1", 2012, "1.00");
_tempValue.add(_iTDTO);
_iTDTO = new IndicatorTableDTO("iName", "dName", "countryName2", 2012, "");
_tempValue.add(_iTDTO);
_iTDTO = new IndicatorTableDTO("iName", "dName", "countryName3", 2012, "0.02");
_tempValue.add(_iTDTO);
_iTDTO = new IndicatorTableDTO("iName", "dName", "countryName4", 2012, "-0.25");
_tempValue.add(_iTDTO);
_iTDTO = new IndicatorTableDTO("iName", "dName", "countryName5", 2012, "0.10");
_tempValue.add(_iTDTO);

mapOfIndicators.put("Test1", _tempValue);

   _iTDTO = new IndicatorTableDTO("iName", "dName", "countryName1", 2012, "0.10");
   _tempValue.add(_iTDTO);
   _iTDTO = new IndicatorTableDTO("iName", "dName", "countryName2", 2012, "", "", "");
   _tempValue.add(_iTDTO);
   _iTDTO = new IndicatorTableDTO("iName", "dName", "countryName3", 2012, "", "", "");
   _tempValue.add(_iTDTO);
   _iTDTO = new IndicatorTableDTO("iName", "dName", "countryName4", 2012, "0.25", "", "");
   _tempValue.add(_iTDTO);
   _iTDTO = new IndicatorTableDTO("iName", "dName", "countryName5", 2012, "1.10", "", "");
   _tempValue.add(_iTDTO);

   mapOfIndicators.put("Test2", _tempValue);
Map<String, Double> averages=mapOfIndicators.entrySet().stream()
    .collect(Collectors.toMap(Map.Entry::getKey, e->e.getValue().stream()
       .map(ObjectDTO::getNewIndex).filter(str->!str.isEmpty())
       .mapToDouble(Double::parseDouble).average().orElse(Double.NaN)));
Map<String, Double> averages=mapOfIndicators.values().stream()
    .flatMap(Collection::stream)
    .filter(objectDTO -> !objectDTO.getNewIndex().isEmpty())
    .collect(Collectors.groupingBy(ObjectDTO::getCountryName,
        Collectors.mapping(ObjectDTO::getNewIndex,
            Collectors.averagingDouble(Double::parseDouble))));
Map<String, Double> averageByCountryName = 
    map.values()
       .stream()
       .flatMap(list -> list.stream())
       .filter(objectDTO -> !objectDTO.getNewIndex().isEmpty())
       .collect(Collectors.groupingBy(
            ObjectDTO::getCountry,
            Collectors.averagingDouble(
                objectDTO -> Double.parseDouble(objectDTO.getNewIndex())));