1
for (a = 0; a < filename; a++) {
  Map<Double,String> m = new HashMap<Double,String>();

  String pre = "abc";
  String post = ".txt";
  for (int ii = 0; ii < 11; ii++) {
    m.put(similarityScore[a],pre + a + post + '\n');
  }
  SortedSet<Double> set = new TreeSet<Double>(m.keySet());
  for (Double d : set) {
    System.out.println(d + " " + m.get(d));
  }
}

输出 :

0.5773502691896258 abc0.txt
0.5773502691896258 abc1.txt
0.5773502691896258 abc2.txt
NaN abc3.txt
0.5773502691896258 abc4.txt
NaN abc5.txt
NaN abc6.txt
NaN abc7.txt
NaN abc8.txt
0.5773502691896258 abc9.txt
NaN abc10.txt

此代码应该能够对双精度值进行排序。但它会在顶部显示输出。发生什么事 ?

4

4 回答 4

2

这个问题几乎可以肯定NaN

顾名思义,这不是一个实数,并且在比较方面表现得非常奇怪。是NaN大于、等于还是小于0.5773502691896258?它可以是这些结果中的任何一个,甚至不需要在程序的单次执行中保持一致。 NaN甚至不等于自身,这说明了平等法则和强秩序的先入之见在涉及时如何消失NaN

所以解决方法是不要使用非数字并期望Double.compareTo()用它做你想做的事。根据从 返回时的NaN 含义similarityScore(),您可以采取多种方法。如果这意味着它根本不匹配,您可以让该方法返回 a Double(而不是 a double),null在这些情况下返回,然后只将非空结果添加到映射中。如果无论如何都应该显示这些结果,那么也许您可以使用0.0or的结果-1.0,假设它小于任何“真实”相似性分数。如果您想要更精细的东西,那么返回像原始双精度一样纯粹和直接的东西可能会成为问题,您可能需要返回自己的(简单)域类。


顺便说一句 - 你到底为什么要创建和填充 a HashMap,然后使用 aTreeSet来获取键的迭代顺序?如果您只是创建mTreeMap<Double, String> you get exactly the iteration order you want, so can just iterate overm.entrySet()`。它更清晰、更惯用(因此更容易理解)、更高效,因此没有理由不这样做。

于 2011-03-27T12:15:09.473 回答
2
for (int ii = 0; ii < 11; ii++) {
    m.put(similarityScore[a],pre + a + post + '\n');
}

这会将相同的值放入地图 11 次 - 您没有在循环内引用 ii 。

for (Double d : set) {
    System.out.println(d + " " + m.get(d));
}

这将打印地图中的单个条目。

您对值执行上述操作0..filename- 多次向地图添加值,然后打印它并使用新地图重新启动。

Map<Double,String> m = new HashMap<Double,String>();
for (a = 0; a < filename; a++) {
  String pre = "abc";
  String post = ".txt";
  m.put(similarityScore[a],pre + a + post + '\n');
}
SortedSet<Double> set = new TreeSet<Double>(m.keySet());
for (Double d : set) {
  System.out.println(d + " " + m.get(d));
}

这将创建一个地图,用 的值填充它0..filename,然后将其打印出来。您仍然会NaN遇到无法真正排序的问题。

Map<Double,String> m = new TreeMap<Double,String>();
for (a = 0; a < filename; a++) {
  String pre = "abc";
  String post = ".txt";
  m.put(similarityScore[a],pre + a + post + '\n');
}
for (Double d : m.keySet()) {
  System.out.println(d + " " + m.get(d));
}

这使用了TreeMap- 不需要中间Set

于 2011-03-27T12:15:48.117 回答
0

您的循环意味着您要分别对每个文件名进行排序。您需要将排序拉出循环以对这些值进行排序。(哎呀,@Eric 打败了我。)

于 2011-03-27T12:22:02.847 回答
0

对于要排序的任何集合,您要排序的值的类型应该相同。并且应该实现类似的接口。

在您的情况下,您需要对 NaN 和 Double 值进行排序。

于 2011-03-27T12:16:03.097 回答