无法对以下树形图进行排序

时间:2011-03-27 12:08:16

标签: java loops treeset

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

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

4 个答案:

答案 0 :(得分:2)

问题几乎肯定是NaN

顾名思义,这不是真正的数字,在比较方面表现得非常奇怪。 NaN大于,等于或小于0.5773502691896258吗?它可以是任何结果,甚至不需要在程序的单次执行中保持一致。 NaN甚至不等于它本身,它说明了在涉及NaN时,对平等法则和强烈排序的先入之见是如何摆脱困境的。

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


顺便说一句 - 为什么你要创建并填充HashMap,然后使用TreeSet获取密钥的迭代顺序?如果您只是将m创建为TreeMap<Double, String> you get exactly the iteration order you want, so can just iterate over m.entrySet()`。它更清晰,更惯用(因此更容易理解),效率更高,因此没有理由不这样做。

答案 1 :(得分: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

答案 2 :(得分:0)

对于要排序的任何Collection,您要排序的值的类型应该相同。并且应该实现类似的界面。

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

答案 3 :(得分:0)

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