Java 8 流最小值未返回预期值
Java 8 stream min is not returning expected value
我希望从 java 中的地图列表中获取最小值。我使用 flatmap、stream 和 min 的组合来这样做,但没有得到预期的结果。这是代码
public class TestMin {
public static class TestHolder{
public static Map<String,Integer> getValues(){
Map<String,Integer> map = new HashMap<>();
map.put("a",1);
map.put("b",3);
map.put("c",2);
return map;
}
}
public static void main(String[] args) {
List<Map<String, Integer>> l = new ArrayList<>();
l.add(TestHolder.getValues());
l.add(TestHolder.getValues());
l.add(TestHolder.getValues());
// Getting min
int min = l.stream().map((m)->m.values()).flatMap((v)->v.stream()).min(Integer::min).get();
System.out.println(min);
}
}
输出为:2
当然,我期望的输出是 1。尝试一些调试表明它正在为输出提供对应于 "c" 的值。即如果地图看起来像
[a->2 , b->3, c->1]
那么我得到的输出是1。
问题是为什么它不按值排序而是按键排序并为我提供意外的输出。
Stream::min
期望遵守 Comparator
合同。但是 Integer::min
不会那样做,它只是 returns 它的两个输入中的最小值。您应该改用 Integer::compare
。
您可以使用 mapToInt()
函数将 Stream<Integer>
转换为 IntStream
,然后只需调用 min()
即可:
int min = l.stream()
.map(Map::values)
.flatMap(Collection::stream)
.mapToInt(Integer::intValue)
.min().orElse(defaultMinValue);
我希望从 java 中的地图列表中获取最小值。我使用 flatmap、stream 和 min 的组合来这样做,但没有得到预期的结果。这是代码 public class TestMin {
public static class TestHolder{
public static Map<String,Integer> getValues(){
Map<String,Integer> map = new HashMap<>();
map.put("a",1);
map.put("b",3);
map.put("c",2);
return map;
}
}
public static void main(String[] args) {
List<Map<String, Integer>> l = new ArrayList<>();
l.add(TestHolder.getValues());
l.add(TestHolder.getValues());
l.add(TestHolder.getValues());
// Getting min
int min = l.stream().map((m)->m.values()).flatMap((v)->v.stream()).min(Integer::min).get();
System.out.println(min);
}
}
输出为:2
当然,我期望的输出是 1。尝试一些调试表明它正在为输出提供对应于 "c" 的值。即如果地图看起来像
[a->2 , b->3, c->1]
那么我得到的输出是1。 问题是为什么它不按值排序而是按键排序并为我提供意外的输出。
Stream::min
期望遵守 Comparator
合同。但是 Integer::min
不会那样做,它只是 returns 它的两个输入中的最小值。您应该改用 Integer::compare
。
您可以使用 mapToInt()
函数将 Stream<Integer>
转换为 IntStream
,然后只需调用 min()
即可:
int min = l.stream()
.map(Map::values)
.flatMap(Collection::stream)
.mapToInt(Integer::intValue)
.min().orElse(defaultMinValue);