将总和作为值放入哈希图中

Put a sum as value in a hashmap

我的两个列表 list2filetemp 的长度相同,并且包含日期和温度。列表中的一些元素如下所示:

[1946-01-12, 1946-01-12, 1946-01-12, 1946-01-13, 1946-01-13, 1946-01-13, 1946-01-14, 1946-01-14, 1946-01-14]
[-1.3, 0.3, -2.8, -6.2, -4.7, -4.3, -1.5, -0.2, -0.4]

我想把它们放在一个以日期为键、以温度为值的哈希图中。由于我有几个对应于每个日期的温度值,我想对每天的温度值求和(或者如果可能的话计算每天的平均温度),以便地图中的每个日期都对应于该日期的平均温度。我现在的问题是我的地图看起来像:

1946-01-12: -2.8
1946-01-13: -4.3
1946-01-14: -0.4

因此,不是对日期 1946-01-14 求和,例如 -1.5+(-0.2)+(-0.4),而是 returns 该日期的最后温度。有人知道怎么解决吗?

public Map<LocalDate, Double> avarageTemperatures(LocalDate dateFrom, LocalDate dateTo) {
    List<LocalDate> list2 = new ArrayList<>();
    for (Weather weather : weatherData) {
        list2.add(weather.getDateTime());
    }

    Map<LocalDate, Double> map = new HashMap<>();
    List<Double> filetemp = new ArrayList<>();
    for (Weather weather : weatherData) {
        filetemp.add(weather.getTemperature());
    }
    Double val= 0.0;
    for (int i=1; i<list2.size(); i++) {
        if(list2.get(i)==list2.get(i-1)) {
            val+= filetemp.get(i);
            map.put(list2.get(i), val);
        } else {
            val=filetemp.get(i);
            map.put(list2.get(i), val);
        }
    }

    Set<Map.Entry<LocalDate, Double>> entrySet = map.entrySet();
    for(Map.Entry<LocalDate,Double> entry : entrySet) {
        if(!entry.getKey().isAfter(dateTo) && !entry.getKey().isBefore(dateFrom)) {
            System.out.println(entry.getKey()+": "+(entry.getValue()));
        }
    }

    return map;
}

这是您可以做到的一种方式。要像您一样获取天气对象列表,我们使用字符串数组和双精度值数组创建天气对象列表。从该列表中,我们简单地使用 Collectors#groupingBy 进行收集,这使我们能够确定我们要分组的键,在本例中为 LocalDate,而 Collector 用于将所有相关键值组合在一起,在本例中为 Collectors# summingDouble 因为我们想对所有双精度值求和。

        String[] dates = {
                "1946-01-12", "1946-01-12", "1946-01-12", "1946-01-13", "1946-01-13", "1946-01-13",
                "1946-01-14", "1946-01-14", "1946-01-14"
        };

        double[] temperatures = {-1.3, 0.3, -2.8, -6.2, -4.7, -4.3, -1.5, -0.2, -0.4};

        class Weather {

            private final LocalDate date;

            private final double temperature;

            Weather(LocalDate date, double temperature) {
                this.date = date;
                this.temperature = temperature;
            }

            public LocalDate getDate() {
                return date;
            }

            public double getTemperature() {
                return temperature;
            }
        }

        List<Weather> weather = IntStream.range(0, dates.length)
                .mapToObj(index -> new Weather(LocalDate.parse(dates[index]), temperatures[index]))
                .collect(Collectors.toList());        

       Map<LocalDate, Double> temperaturesSum = weather.stream()
                .collect(Collectors.groupingBy(Weather::getDate,
                        Collectors.summingDouble(Weather::getTemperature)));

        Map<LocalDate, Double> temperaturesAverage = weather.stream()
                .collect(Collectors.groupingBy(Weather::getDate,
                        Collectors.averagingDouble(Weather::getTemperature)));

        System.out.println("sum: " + temperaturesSum);
        System.out.println("average: " + temperaturesAverage);

输出

sum: {1946-01-12=-3.8, 1946-01-13=-15.2, 1946-01-14=-2.1}
average: {1946-01-12=-1.2666666666666666, 1946-01-13=-5.066666666666666, 1946-01-14=-0.7000000000000001}

希望对您有所帮助:

    List<String> dates = Arrays.asList("1946-01-12", "1946-01-12", "1946-01-12", "1946-01-13", "1946-01-13", "1946-01-13", "1946-01-14", "1946-01-14", "1946-01-14");
    List<Double> values = Arrays.asList(-1.3, 0.3, -2.8, -6.2, -4.7, -4.3, -1.5, -0.2, -0.4);

    Map<String, DoubleSummaryStatistics> res = IntStream
            .range(0, dates.size())
            .boxed()
            .map(index -> new Pair<>(dates.get(index), values.get(index)))
            .collect(groupingBy(Pair::getKey,
                    summarizingDouble(Pair::getValue)));

    System.out.println(res);

结果:

{1946-01-14=DoubleSummaryStatistics{count=3, sum=-2.100000, min=-1.500000, average=-0.700000, max=-0.200000}, 
1946-01-12=DoubleSummaryStatistics{count=3, sum=-3.800000, min=-2.800000, average=-1.266667, max=0.300000}, 
1946-01-13=DoubleSummaryStatistics{count=3, sum=-15.200000, min=-6.200000, average=-5.066667, max=-4.300000}}

好吧,这是使用 streams 并创建地图中的地图的一种方法。内部地图只包含 sumaverage 温度。也可以使用 List,但地图允许使用符号索引来帮助保持正确。

它的工作原理如下:

  • 使用Collectors.teeing方法创建两个流。第一个对日期进行频率计数。第二,添加临时工。两者都以日期作为键结束在地图中。
  • 然后用总和除以日期的频率计数来计算平均温度。这允许每个样本的日期数量在数量上有所不同,并且仍然允许准确的平均值。
  • 温度总和和平均温度都存储为地图。
  • A TreeMap 用于外部映射以按自然顺序对键进行排序。

    List<String> dates =
            List.of("1946-01-12", "1946-01-12", "1946-01-12",
                    "1946-01-13", "1946-01-13", "1946-01-13",
                    "1946-01-14", "1946-01-14", "1946-01-14");

    List<Double> temps = List.of(-1.3, 0.3, -2.8, -6.2, -4.7,
            -4.3, -1.5, -0.2, -0.4);

    Map<String,Map<String, Double>> data = IntStream
            .range(0,
                    dates.size())
            .boxed()
            .collect(Collectors.teeing(
                    Collectors.groupingBy(i -> dates.get(i),
                            Collectors.counting()),
                    Collectors.groupingBy(i -> dates.get(i),
                            Collectors.summingDouble(
                                    i -> temps.get(i))),
                    (counts, temp) -> temp.keySet().stream()
                            .collect(Collectors.toMap(k->k,
                                    k->Map.of("SUM", temp.get(k), "AVG",temp.get(k)
                                            / counts.get(k)), (m,n)->n, TreeMap::new))));



    for (String k : data.keySet())  {
        System.out.printf("For %s - sum of temperatures was %6.3f%n",k,data.get(k).get("SUM"));
        System.out.printf("For %s - average temp was %6.3f%n",k,data.get(k).get("AVG"));
        System.out.println();
     }

它打印以下内容:

For 1946-01-12 - sum of temperatures was -3.800
For 1946-01-12 - average temp was -1.267

For 1946-01-13 - sum of temperatures was -15.200
For 1946-01-13 - average temp was -5.067

For 1946-01-14 - sum of temperatures was -2.100
For 1946-01-14 - average temp was -0.700