使用Java8流API处理HashMap
我在表单中有一个哈希表使用Java8流API处理HashMap,java,hashmap,java-stream,Java,Hashmap,Java Stream,我在表单中有一个哈希表 Map<String, Map<String,Double> 特别是,输出必须具有相同的键(id1,…,IDN) 内部哈希表必须具有固定键(1/1/1800)和已处理值 我的当前(不工作)代码: output=input.entrySet() .stream() .收集( Collectors.toMap(entry->entry.getKey(), 条目->收集器.toMap( e->“1/1/2000”, e->{ //获取输入数组 List Li
Map<String, Map<String,Double>
特别是,输出必须具有相同的键(id1,…,IDN)
内部哈希表必须具有固定键(1/1/1800)和已处理值
我的当前(不工作)代码:
output=input.entrySet()
.stream()
.收集(
Collectors.toMap(entry->entry.getKey(),
条目->收集器.toMap(
e->“1/1/2000”,
e->{
//获取输入数组
List List=entry.getValue().values().stream()
.collect(Collectors.toList());
DescriptiveStatistics stats=新的DescriptiveStatistics();
//从输入数组中删除NaN值
列表。forEach(v->{
如果(!new Double((Double)v).isNaN())
统计附加值((双)v);
});
double value=stats.max();
返回值;
}));
问题在哪里
谢谢问题是试图调用
收集器。toMap
在第一个收集器内的第二种类型。toMap
收集器。toMap
应传递给接受收集器的方法
有一种方法可以实现您的目标:
Map<String, Map<String,Double>>
output = input.entrySet()
.stream()
.collect(Collectors.toMap(e -> e.getKey(),
e -> Collections.singletonMap (
"1/1/1800",
e.getValue()
.values()
.stream()
.filter (d->!Double.isNaN (d))
.mapToDouble (Double::doubleValue)
.max()
.orElse(0.0))));
Map
output=input.entrySet()
.stream()
.collect(Collectors.toMap(e->e.getKey(),
e->Collections.singletonMap(
"1/1/1800",
e、 getValue()
.values()
.stream()
.filter(d->!Double.isNaN(d))
.mapToDouble(双精度::双精度值)
.max()
.orElse(0.0));
请注意,不需要第二个Collectors.toMap
。输出的内部Map
s每个都有一个条目,因此您可以使用Collections.singletonMap
创建它们。问题是试图调用收集器.toMap
第一个收集器内的第二个类型。toMap
Collectors.toMap
应传递给接受收集器的方法
有一种方法可以实现您的目标:
Map<String, Map<String,Double>>
output = input.entrySet()
.stream()
.collect(Collectors.toMap(e -> e.getKey(),
e -> Collections.singletonMap (
"1/1/1800",
e.getValue()
.values()
.stream()
.filter (d->!Double.isNaN (d))
.mapToDouble (Double::doubleValue)
.max()
.orElse(0.0))));
Map
output=input.entrySet()
.stream()
.collect(Collectors.toMap(e->e.getKey(),
e->Collections.singletonMap(
"1/1/1800",
e、 getValue()
.values()
.stream()
.filter(d->!Double.isNaN(d))
.mapToDouble(双精度::双精度值)
.max()
.orElse(0.0));
请注意,不需要第二个收集器。toMap
。输出的内部映射
各有一个条目,因此您可以使用集合。singletonMap
来创建它们。您的原始代码可以使用集合来解决。singletonMap
而不是收集器。toMap
Map<String, Map<String,Double>> output = input.entrySet()
.stream()
.collect(
Collectors.toMap(entry -> entry.getKey(),
entry -> {
// Get input array
List<Object> list = entry.getValue().values().stream()
.collect(Collectors.toList());
DescriptiveStatistics stats = new DescriptiveStatistics();
// Remove the NaN values from the input array
list.forEach(v -> {
if(!new Double((double)v).isNaN())
stats.addValue((double)v);
});
double value = stats.max();
return Collections.singletonMap("1/1/2000", value);
}));
虽然这是一个安静的巴洛克式的解决方案
这就是说,您应该知道有一个标准使得DescriptiveStatistics
不必要,但是,如果您只想获得最大值,这两个标准都是不必要的
此外,List List=e.values().stream().collect(Collectors.toList());
可以简化为List=new ArrayList(e.values());
如果确实需要List
,但是这里,Collection List=e.values();
就足够了,用Double
而不是Object
键入集合就不需要后续的类型转换
在第一个变体中使用这些改进,您将获得
Map<String, Map<String,Double>> output = input.entrySet()
.stream()
.collect(
Collectors.toMap(entry -> entry.getKey(),
entry -> {
Collection<Double> list = entry.getValue().values();
DoubleSummaryStatistics stats = new DoubleSummaryStatistics();
list.forEach(v -> {
if(!Double.isNaN(v)) stats.accept(v);
});
double value = stats.getMax();
return Collections.singletonMap("1/1/2000", value);
}));
请注意,double
如果至少有一个值是NaN
,则比较结果总是计算为false
,因此使用正确的运算符,即“value-mably-NaN”>“current max-never-NaN”,我们不需要额外的条件
现在,您可以用流操作替换循环,最终结果是。选择权在您。您的原始代码可以使用集合来解决。singletonMap
而不是收集器。toMap
Map<String, Map<String,Double>> output = input.entrySet()
.stream()
.collect(
Collectors.toMap(entry -> entry.getKey(),
entry -> {
// Get input array
List<Object> list = entry.getValue().values().stream()
.collect(Collectors.toList());
DescriptiveStatistics stats = new DescriptiveStatistics();
// Remove the NaN values from the input array
list.forEach(v -> {
if(!new Double((double)v).isNaN())
stats.addValue((double)v);
});
double value = stats.max();
return Collections.singletonMap("1/1/2000", value);
}));
虽然这是一个安静的巴洛克式的解决方案
这就是说,您应该知道有一个标准使得DescriptiveStatistics
不必要,但是,如果您只想获得最大值,这两个标准都是不必要的
此外,List List=e.values().stream().collect(Collectors.toList());
可以简化为List=new ArrayList(e.values());
如果确实需要List
,但是这里,Collection List=e.values();
就足够了,用Double
而不是Object
键入集合就不需要后续的类型转换
在第一个变体中使用这些改进,您将获得
Map<String, Map<String,Double>> output = input.entrySet()
.stream()
.collect(
Collectors.toMap(entry -> entry.getKey(),
entry -> {
Collection<Double> list = entry.getValue().values();
DoubleSummaryStatistics stats = new DoubleSummaryStatistics();
list.forEach(v -> {
if(!Double.isNaN(v)) stats.accept(v);
});
double value = stats.getMax();
return Collections.singletonMap("1/1/2000", value);
}));
注意
Map<String, Map<String,Double>> output = input.entrySet()
.stream()
.collect(Collectors.toMap(entry -> entry.getKey(),
entry -> {
double max = Double.NEGATIVE_INFINITY;
for(double d: entry.getValue().values())
if(d > max) max = d;
return Collections.singletonMap("1/1/2000", max);
}));