我试图打印HashMap的最大值。
这是一个静态变量,在Results.java中定义如下
public static HashMap<Double,Double> true_false=new LinkedHashMap<>();
我在另一个类中访问它,当我打印HashMap时,它打印得很好。
public double print_maxThreshold(){
double maxValueInMap = (Collections.max(Results.true_false.values()));
}
当Results.true_false打印结果时,如下所示。
{0.01 = 0.5714285714285714,0.05 = 0.5714285714285714,0.1 = 0.6190476190476191,0.15000000000000002 = 0.5405405405405405,0.2 = 0.5625,0.25 = 0.5714285714285715,0.3 = 0.34782608695652173,0.35 = 0.3157894736842105,0.39999999999999997 = 0.2222222222222222,0.44999999999999996 = 0.11764705882352941,0.49999999999999994 = 0.11764705882352941,0.5499999999999999 = NaN,0.6 = NaN,0.65 = NaN,0.7000000000000001 = NaN,0.7500000000000001 = NaN,0.8000000000000002 = NaN,0.8500000000000002 = NaN,0.9000000000000002 = NaN,0.9500000000000003 = NaN}
但为什么最大值不会打印为0.6190476190476191
请有人好心解释
答案 0 :(得分:3)
Collections.max(Collection<? extends T> coll)
的Javadoc说:
根据元素的自然排序 返回给定集合的最大元素。集合中的所有元素都必须实现
Comparable
接口。此外,集合中的所有元素必须相互比较(即e1.compareTo(e2)
不得为任何元素ClassCastException
和e1
抛出e2
在集合中。)
这意味着排序由Double.compareTo(Double anotherDouble)
方法定义,该方法具有以下javadoc描述:
此方法认为Double.NaN
等于自身且大于所有其他double
值(包括Double.POSITIVE_INFINITY
)。
这意味着,如果集合中有NaN
个值,max()
将返回NaN
。
<强>更新强>
要排除NaN
被考虑,请使用Java 8流:
double maxValueInMap = Results.true_false
.values()
.stream()
.mapToDouble(Double::doubleValue)
.filter(d -> ! Double.isNaN(d))
.max()
.orElseThrow(NoSuchElementException::new);
优于your self-answer的优势在于它不会修改原始Map
。
答案 1 :(得分:1)
与NaN的比较是undefined:
NaN是无序的,因此如果其中一个或两个操作数都是NaN(§15.20.1),则数值比较运算符&lt;,&lt; =,&gt;和&gt; =返回false。如果任一操作数是NaN,则等于运算符==返回false,如果任一操作数是NaN(第15.21.1节),则不等式运算符!=返回true。特别是,当且仅当x是NaN时,x!= x才为真,如果x或y是NaN,则(x = y)将为假。
但是作为@Andreas pointed out,正确的理由是Double.compareTo()认为NaN大于所有其他双重值。
答案 2 :(得分:0)
嗨朋友们感谢您的建议。
根据您的建议,可以像这样解决。
public double print_maxThreshold(){
Results.true_false.values().removeAll(Collections.singleton(NaN));
double maxValueInMap = (Collections.max(Results.true_false.values()));
}
现在最大值打印正常。