- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我有这样的温度记录
dt |AverageTemperature |AverageTemperatureUncertainty|City |Country |Latitude|Longitude
----------+-------------------+-----------------------------+-------+--------+--------+---------
1963-01-01|-5.417000000000002 |0.5 |Karachi|Pakistan|57.05N |10.33E
1963-02-01|-4.7650000000000015|0.328 |Karachi|Pakistan|57.05N |10.33E
1964-01-01|-5.417000000000002 |0.5 |Karachi|Pakistan|57.05N |10.33E
1964-02-01|-4.7650000000000015|0.328 |Karachi|Pakistan|57.05N |10.33E
1965-01-01|11.417000000000002 |0.5 |Karachi|Pakistan|57.05N |10.33E
1965-02-01|12.7650000000000015|0.328 |Karachi|Pakistan|57.05N |10.33E
我必须将其解析为 POJO 并根据以下问题陈述计算平均增量:
Use the Streams API to calculate the average annual temperature delta for each country. To calculate delta the average temperature in 1900 would be subtracted from the average temperature in 1901 to obtain the delta from 1900 to 1901 for a particular city. The average of all these deltas is the average annual temperature delta for a city. The average of all cities in a country is the average of a country.
我的 Temperate POJO 看起来像下面有 getter 和 setter
public class Temperature {
private java.util.Date date;
private double averageTemperature;
private double averageTemperatureUncertainty;
private String city;
private String country;
private String latitude;
private String longitude;
}
我维护了一个温度列表,因为这个问题将使用流来解决。
为了计算增量,我尝试使用以下流,但我仍然无法计算实际增量,因为我必须计算平均国家增量,我已经对国家、城市和日期进行了分组。
Map<String, Map<String, Map<Integer, Double>>> countriesMap = this.getTemperatures().stream()
.sorted(Comparator.comparing(Temperature::getDate))
.collect(Collectors.groupingBy(Temperature::getCountry,
Collectors.groupingBy(Temperature::getCity,
Collectors.groupingBy
(t -> {
Calendar calendar = Calendar.getInstance();
calendar.setTime(t.getDate());
return calendar.get(Calendar.YEAR);
},
Collectors.averagingDouble(Temperature::getAverageTemperature)))));
为了计算增量,我们必须计算差异对于 Map<Integer, Double>
.
为了计算差异,我想出了以下代码,但无法将以下代码与上面的代码联系起来
Stream.of(10d, 20d, 10d) //this is sample data that I that I get in `Map<Integer, Double>` of countriesMap
.map(new Function<Double, Optional<Double>>() {
Optional<Double> previousValue = Optional.empty();
@Override
public Optional<Double> apply(Double current) {
Optional<Double> value = previousValue.map(previous -> current - previous);
previousValue = Optional.of(current);
return value;
}
})
.filter(Optional::isPresent)
.map(Optional::get)
.forEach(System.out::println);
如何一次性使用流计算增量或如何对 countriesMap
执行流操作为了计算delta并实现上述问题陈述。?
最佳答案
要将问题陈述缩减为更小的 block ,您可以研究的另一种方法是通过 year
进行解析。温度并为它们计算增量,进一步average
正在处理它。尽管必须对 Map<Integer, Double>
类型的所有值执行此操作内内Map
在你的问题中。它看起来像:
Map<Integer, Double> unitOfWork = new HashMap<>(); // innermost map you've attained ('yearToAverageTemperature' map)
unitOfWork = unitOfWork.entrySet()
.stream()
.sorted(Map.Entry.comparingByKey())
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e1, LinkedHashMap::new));
// the values sorted based on the year from a sorted map
List<Double> srtedValPerYear = new ArrayList<>(unitOfWork.values());
// average of deltas from the complete list
double avg = IntStream.range(0, srtedVal.size() - 1)
.mapToDouble(i -> (srtedVal.get(i + 1) - srtedVal.get(i)))
.average().orElse(Double.NaN);
进一步注意,这只是一个 City
的平均值<Year, AverageTemperature>
的记录,您将不得不遍历所有 City
keyset 和类似的所有 Country
键集以详尽地找出此类平均值。
进一步将这个工作单元移动到一个方法中,遍历整个 map 的 map ,这可能会完成为:
// The average of all cities in a country is the average of a country.
AtomicReference<Double> countryValAvg = new AtomicReference<>(0.0);
countriesMap.forEach((country, cityMap) -> {
// The average of all these deltas is the average annual temperature delta for a city.
AtomicReference<Double> cityAvgTemp = new AtomicReference<>((double) 0);
cityMap.forEach((city, yearMap) -> cityAvgTemp.set(cityAvgTemp.get() + averagePerCity(yearMap)));
double avgAnnualTempDeltaPerCity = cityAvgTemp.get() / cityMap.size();
countryValAvg.set(countryValAvg.get() + avgAnnualTempDeltaPerCity);
});
System.out.println(countryValAvg.get() / countriesMap.size());
哪里averagePerCity
是执行以下操作的方法
double averagePerCity(Map<Integer, Double> unitOfWork) {
unitOfWork = unitOfWork.entrySet()
.stream()
.sorted(Map.Entry.comparingByKey())
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e1, LinkedHashMap::new));
List<Double> srtedVal = new ArrayList<>(unitOfWork.values());
return IntStream.range(0, srtedVal.size() - 1)
.mapToDouble(i -> (srtedVal.get(i + 1) - srtedVal.get(i)))
.average().orElse(Double.NaN);
}
注意:上面的代码可能缺少验证,它只是提供一个想法,说明如何将完整的问题分解成更小的部分,然后再解决。
Edit1:哪个could be improved further as :
// The average of all cities in a country is the average of a country.
AtomicReference<Double> countryValAvg = new AtomicReference<>(0.0);
countriesMap.forEach((country, cityMap) -> {
// The average of all these deltas is the average annual temperature delta for a city.
double avgAnnualTempDeltaPerCity = cityMap.values()
.stream()
.mapToDouble(Quick::averagePerCity) // Quick is my class name
.average()
.orElse(Double.NaN);
countryValAvg.set(countryValAvg.get() + avgAnnualTempDeltaPerCity);
});
System.out.println(countryValAvg.get() / countriesMap.size());
Edit2:进一步
double avgAnnualTempDeltaPerCity = countriesMap.values().stream()
.mapToDouble(cityMap -> cityMap.values()
.stream()
.mapToDouble(Quick::averagePerCity) // Quick is my class name
.average()
.orElse(Double.NaN))
.average().orElse(Double.NaN);
关于Java 8 Streams 多重分组依据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54132104/
我正在尝试实现具有以下签名的方法: public static Pair, Stream> flatten(Iterator, Stream>> iterator); 该方法的目标是将每种流类型展平
我有两个流从两个不同的 api 获取。 Stream get monthOutStream => monthOutController.stream; Stream get resultOutStre
Stream.of(int[])返回 Stream ,而 Stream.of(String[])返回 Stream . 为什么这两种方法的行为不同?两者都应该返回 Stream和 Stream或 St
我正在使用 rxdart在 dart 中处理流的包。我被困在处理一个特殊的问题上。 请看一下这个虚拟代码: final userId = BehaviorSubject(); Stream getSt
我到处都找遍了,还是没弄明白。我知道你可以用流建立两个关联: 用于支持数据存储的包装器意味着作为消费者和供应商之间的抽象层 数据随着时间的推移变得可用,而不是一次全部 SIMD 代表单指令,多数据;在
考虑下面的代码: List l=new ArrayList<>(); l.add(23);l.add(45);l.add(90); Stream str=l.stream
我有一个大型主干/requirejs 应用程序,我想迁移到 webpack,最新的“webpack”:“^4.27.1”,但我遇到了一个我无法解决的错误。 我一直在阅读 https://webpack
我正在使用 xmpp 开发聊天应用程序,根据我们的要求,我们有三台服务器 Apache Tomcat 7、ejabbered 2.1.11 和 mysql 5.5, to run xmppbot on
我知道如何使用 Java 库,并且我可以编写一些循环来执行我需要的操作,但问题更多,为什么 scala.collection.JavaConverters 中没有任何内容或scala.collecti
我正在尝试创建一个单一的衬里,它应该计算一个非常长的文本文件中的唯一单词。独特的词例如:márya fëdorovna scarlet-liveried,...所以基本上都是非英语词。 我的问题是我的
如果我有以下情况: StreamWriter MySW = null; try { Stream MyStream = new FileStream("asdf.txt"); MySW =
有人可以帮我将以下语句转换为 Java8: 我有一个像这样的 HashMap : private Map, List>> someMap; 我想在java8中转换以下逻辑: private Strin
有人可以帮我将以下语句转换为 Java8: 我有一个像这样的 HashMap : private Map, List>> someMap; 我想在java8中转换以下逻辑: private Strin
考虑两种测试方法parallel()和sequential(): @Test public void parallel() throws Exception { System.ou
我是 NodeJS 的新手,我基本上想做的是通过 HTTP 将 .pdf 上传到我的服务器。我正在使用 POST rquest 来处理 Content-Type multipart/form-data
哪个更好:MemoryStream.WriteTo(Stream destinationStream) 或 Stream.CopyTo(Stream destinationStream)?? 我正在谈
给定一个 Stream,我想创建一个新的 Stream,其中的元素在它们之间有时间延迟。 我尝试使用 tokio_core::reactor::Timeout 和 Stream 的 and_then
我是 Kafka Streams 和 Spring Cloud Stream 的新手,但在将集成相关代码移动到属性文件方面已经阅读了有关它的好东西,因此开发人员可以主要专注于事物的业务逻辑方面。 这里
源代码看起来非常相似:pump , pipe .为什么我要使用一个而不是另一个?一个只是另一个的更好版本吗? 最佳答案 Stream.pipe 现在显然是自 0.3.x 以来的首选方法,因此尽可能尝试
我正在寻找是否有更好的方法来解决我不得不使用这些签名的困境(注意:由于 Spock 测试,T[][] 是必需的,我提供 T[][] 作为数据提供商) 我的方法签名是: public T[][] cr
我是一名优秀的程序员,十分优秀!