将总和作为值放入哈希图中
Put a sum as value in a hashmap
我的两个列表 list2
和 filetemp
的长度相同,并且包含日期和温度。列表中的一些元素如下所示:
[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
并创建地图中的地图的一种方法。内部地图只包含 sum
和 average
温度。也可以使用 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
我的两个列表 list2
和 filetemp
的长度相同,并且包含日期和温度。列表中的一些元素如下所示:
[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
并创建地图中的地图的一种方法。内部地图只包含 sum
和 average
温度。也可以使用 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