Java 红黑树再平衡问题?
compareTo方法对放入标准java树集合(即实现为红黑树的集合)的对象进行排序是否有任何约束?我有Java 红黑树再平衡问题?,java,collections,Java,Collections,compareTo方法对放入标准java树集合(即实现为红黑树的集合)的对象进行排序是否有任何约束?我有 公共类规则元组实现了可比较的{ 线头; 字符串[]rhs; 公共字符串toString(){ StringBuffer b=新的StringBuffer(); b、 追加(头+“:”); 用于(字符串t:rhs) b、 附加(“+t”); 返回b.toString(); } 公共整数比较(对象对象对象){ 规则元组src=(规则元组)obj; int cmp=头部比较(src头部); 如果(
公共类规则元组实现了可比较的{
线头;
字符串[]rhs;
公共字符串toString(){
StringBuffer b=新的StringBuffer();
b、 追加(头+“:”);
用于(字符串t:rhs)
b、 附加(“+t”);
返回b.toString();
}
公共整数比较(对象对象对象){
规则元组src=(规则元组)obj;
int cmp=头部比较(src头部);
如果(cmp!=0)
返回cmp;
if(rhs.length!=src.rhs.length)
返回rhs.length-src.rhs.length;
对于(int i=0;i,比较器和可比性的另一个(通常被忽略的)条件是“临时一致性”,即,两个对象的比较结果不应改变,只要它们被用作树映射中的键(或使用Comparator/Comparable的任何其他结构,如用于Collections.binarySearch的排序数组,或由最小堆实现的PriorityQueue-即使对于array.sort-在排序完成之前,不应更改元素)
这本质上意味着您的键不应更改,至少不应以顺序更改的方式更改
原因是树映射假定二叉树的节点总是按正确的顺序排列-正因为如此,它可以在O(log(n))
中工作,而不是在O(n)
中进行查找和更改
如果必须更改密钥,应首先将其从结构中删除,然后更改,然后再次添加
(顺便说一句,对于HashMap等基于哈希的结构中的键的equals
和hashCode
也是如此。)
作为额外的奖励,这里有一个使用代码变体的泛型:
public class RuleTuple implements Comparable<RuleTuple> {
String head;
String[] rhs;
public String toString() {
StringBuilder b = new StringBuilder();
b.append(head+":");
for( String t: rhs )
b.append(" "+t);
return b.toString();
}
public int compareTo(RuleTuple src) {
int cmp = head.compareTo(src.head);
if( cmp!=0 )
return cmp;
if( rhs.length != src.rhs.length )
return rhs.length - src.rhs.length;
for( int i=0; i<rhs.length; i++ ) {
int diff = rhs[i].compareTo(src.rhs[i]);
if(diff != 0)
return diff;
}
return 0;
}
...
}
公共类规则元组实现了可比较的{
线头;
字符串[]rhs;
公共字符串toString(){
StringBuilder b=新的StringBuilder();
b、 追加(头+“:”);
用于(字符串t:rhs)
b、 附加(“+t”);
返回b.toString();
}
公共整数比较(规则元组src){
int cmp=头部比较(src头部);
如果(cmp!=0)
返回cmp;
if(rhs.length!=src.rhs.length)
返回rhs.length-src.rhs.length;
对于(int i=0;i另一个条件是“临时一致性”,即比较两个对象的结果不应改变,只要它们在树映射中用作键。这意味着您的键本质上不应改变。这可能是键(双关语)!i do transform(替换规则)在原地.Argh,走捷径时总是有问题…当this.head==null
但是src.head!=null
时会发生什么?我想在切换视点时会出现NullPointerException。另外,您可能会考虑不调用rhs[I].compareTo(src.rhs[I])
两次。(这只是一个优化,不是问题的原因,我真的不明白。)除此之外(你应该在这里使用泛型),您的compareTo方法看起来很好。为了避免一致性问题:从集合/映射中删除规则,对其进行更改,然后再次添加。我编辑了这篇文章,因为空问题与此无关。按照Paulo的建议修复了变异问题后,代码似乎运行良好。这是问题注释中讨论的要点。我碰巧遇到了rand我第一句话就说到了解决办法。
test[22,33): 'HAVING' condition <-- comparison#1
test: test[4,19) group_by_clause <-- comparison#2
test: model_clause <-- comparison#3
test: group_by_clause
test:
test: test[22,33)
test: group_by_clause test[22,33) <-- comparison#4; wrong branch!
test: test[4,19) <-- comparison#5
test: group_by_clause model_clause
...
test: test[4,19) group_by_clause model_clause
...
test[4,19): test[5,8) test[8,11)
...
public class RuleTuple implements Comparable<RuleTuple> {
String head;
String[] rhs;
public String toString() {
StringBuilder b = new StringBuilder();
b.append(head+":");
for( String t: rhs )
b.append(" "+t);
return b.toString();
}
public int compareTo(RuleTuple src) {
int cmp = head.compareTo(src.head);
if( cmp!=0 )
return cmp;
if( rhs.length != src.rhs.length )
return rhs.length - src.rhs.length;
for( int i=0; i<rhs.length; i++ ) {
int diff = rhs[i].compareTo(src.rhs[i]);
if(diff != 0)
return diff;
}
return 0;
}
...
}