我正在尝试用java编写一些数学代码。我想要做的是将 cyclotomic cosets 放到TreeSet中。陪集程序具有索引和一组整数。如果集合具有相同的元素,则陪集等于其他陪集。如果集合不同,则coset按其索引排序。
例如:
C1 = [1, 2, 4, 8]
C3 = [3, 6, 9, 12]
C9 = [3, 6, 9, 12]
C1 is less than C3
C3 is equal to C9
数学足够好。我选择将陪集程序放到TreeSet中,因为我不需要重复的元素,我需要按索引对它们进行排序。
问题是甚至TreeSet.contains()返回false,我仍然可以在TreeSet中找到一个在使用compareTo()和equals()方法时相等的元素。
这是该计划的实际打印输出:
cosets = [C0, C1, C3, C5, C7]
cosets.contains(C9) = false
C0.compareTo(C9) = -1, C0.equals(C9) = false
C1.compareTo(C9) = -1, C1.equals(C9) = false
C3.compareTo(C9) = 0, C3.equals(C9) = true
C5.compareTo(C9) = -1, C5.equals(C9) = false
C7.compareTo(C9) = -1, C7.equals(C9) = false
我附上以下代码。我不想让代码变得更简单,因为我发现它确实有些神奇。如果您在代码中将 MAGIC_INDEX 值更改为7或更低,则它会开始工作。这对我来说似乎是一个JVM错误。
有什么建议吗?
答案 0 :(得分:4)
您的compareTo()
和equals()
方法不一致,因此TreeSet
无法正常使用。
来自API doc:
注意由a维护的排序 设置(无论是否明确 提供比较器)必须 如果是,则与等于一致 正确实现Set接口。 (参见Comparable或Comparator for a 精确定义符合 等于。)这是因为Set 接口是根据的定义的 等于操作,但是一个TreeSet instance执行所有元素 比较使用compareTo(或 比较)方法,所以两个元素 被这种方法认为是平等的, 从集合的角度来看,是平等的。 集合的行为是明确定义的 即使它的排序不一致 与...平等它只是没有服从 Set接口的一般合约。
答案 1 :(得分:3)
Comparable
中的Coset
实施不提供总排序。
您似乎应该在value
TreeSet
上定义订单。在检查index
之前或之后。
答案 2 :(得分:3)
正如我经常说的,如果你的程序中有错误,请使用调试器。这很快就向我展示了你的问题。
TreeSet是一个二叉树。在搜索时,它会根据您要查找的元素是否在它正在检查的元素之前或之后(或相同)向下导航。如果您将以下内容添加到compareTo()
System.out.println("Comparing, "+this+" to "+c);
它会打印出来
Comparing, C9 to C1
Comparing, C9 to C5
Comparing, C9 to C7
问题是C9是在它不匹配的每个元素之后。因此,当它到达树上的C5时,你的compareTo表示它是在它之后,实际上它需要先查看(到达C3)并且搜索沿着树的错误路径行进。