【发布时间】:2013-09-10 08:46:28
【问题描述】:
我有一个通用树类,其中每个树节点都保存一些数据。每条数据都有一个字符串类型的属性。我想按此属性按字母顺序对每个树节点的子节点进行排序。
树类:
public class Tree<T>{
public T data;
public List<Tree<T>> children = new ArrayList<Tree<T>>();
}
请注意,树的子节点是 Tree 类型!
Tree 类的实际类型参数示例如下:
public class DataItem{
public String name;
}
我的想法是使用 sort() 方法扩展 Tree 类,并使用如下所示的 Comparator,但我被比较函数卡住了:
public class Tree<T>{
public T data;
public List<Tree<T>> children = new ArrayList<Tree<T>>();
public void sort(){
Collections.sort(this.children,
new Comparator<Tree<T>>(){
@Override
public int compare(Tree<T> objectA, Tree<T> objectB){
//I am stuck here!
return 0;
}
}
);
for(Tree<T> child: this.children){
child.sort();
}
}
}
我有不同的想法来解决这个问题:
- 使用反射访问对象的属性并进行比较。
- 在 DataItem 中实现接口 Comparable。
-
使用新接口访问对象的属性以进行比较:
public interface GetComparisonAttribute { public String getComparisonAttribute(); } public class DataItem implements GetComparisonAttribute{ public String name; @Override public String GetComparisonAttribute(){ return this.name; } } //the comparison function inside Tree<T>.sort(): public int compare(Tree<T> objectA, Tree<T> objectB){ return objectA.data.getComparisonAttribute() .compareToIgnoreCase(objectB.data.getComparisonAttribute()); }
什么是正确或最好的做法?还有其他方法吗?
能够指定排序属性可能很重要。
我认为直接在树上使用 Collections.sort() 会很好,但是在这种递归数据结构中实现它真的让我感到困惑。这样做的一个缺点是我无法指定排序属性。
【问题讨论】:
-
我只浏览了你的代码,所以我可能遗漏了一些明显的东西,但是你的数据结构在做什么,你不能把你的
children保存在SortedSet中呢? -
我在这里提供的数据结构只是一个最小的例子。它有更多的遍历方法和其他花哨的东西,但它们对问题并不重要。通用数据结构对我来说是一个有趣的话题,所以我希望它能够工作。我不认为 SortedSet 或 TreeSet 可以将数据存储在每个节点中,而只能存储在其叶子中。
-
将孩子放在 SortedSet 中并不能真正解决问题。为此,Tree
必须实现 Comparable,但比较取决于 Tree 的数据属性。嗯,现在我只是认为将数据结构定义为“Tree extends Comparable”解决了部分问题,但它仍然不允许我动态指定 T 的排序属性。 -
如果你想在
Tree中允许特定类型的参数,为什么不给类型参数-T extends DataItem添加边界?在这种情况下,您将能够访问DataItem的属性。 -
@RohitJain The Tree 必须处理任意类型的对象!
标签: java sorting generics tree