我有一个通用树类,其中每个树节点都包含一些数据。每个数据都有一个String类型的属性。我想按此属性按字母顺序对每个树节点的子节目进行排序。
树类:
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();
}
}
}
我有不同的想法来解决这个问题:
使用新界面访问对象的属性进行比较:
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());
}
什么是正确或最好的事情?还有其他方法吗?
能够指定排序属性可能很重要。
我认为直接在Tree上使用Collections.sort()会很好,但在这个递归数据结构中实现它真的让我很困惑。这样做的一个缺点是我无法指定排序属性。
答案 0 :(得分:1)
试试这个:
public class Tree<T> {
public T data;
public List<Tree<T>> children = new ArrayList<Tree<T>>();
private Class<T> type;
public Tree(Class<T> t) {
type = t;
}
public void sort(){
Collections.sort(this.children,
new Comparator<Tree<T>>(){
@Override
public int compare(Tree<T> objectA, Tree<T> objectB){
if (type==DataItem.class)
{
DataItem diA = (DataItem) (objectA.data);
DataItem diB = (DataItem) (objectB.data);
return diA.name.compareTo(diB.name);
}
else
throw new IllegalArgumentException();
}
}
);
for(Tree<T> child: this.children){
child.sort();
}
}
}
创建时,应该传递类Tree的类型T.然后你可以转发到DataItem
并根据你喜欢的文件对列表进行排序。除了DataItem
之外,您当然还可以检查其他类型参数。
答案 1 :(得分:0)
public void sort(final Comparator<? super T> dataComparator)
{
Collections.sort(this.children,
new Comparator<Tree<T>>()
{
@Override
public int compare(Tree<T> treeA, Tree<T> treeB)
{
return dataComparator.compare(treeA.getData(), treeB.getData());
}
}
);
for(Tree<T> child: this.children)
{
child.sort(dataComparator);
}
}
void test()
{
Tree<DataItem> tree = new Tree<>();
tree.sort(new Comparator<DataItem>()
{
@Override
public int compare(DataItem dataA, DataItem dataB)
{
return dataA.getName().compareTo(dataB.getName());
}
});
}
在java8中,这可以简化为
public void sort(final Comparator<? super T> dataComparator)
{
Collections.sort(this.children,
Comparator.comparing(Tree::getData, dataComparator));
for(Tree<T> child: this.children)
{
child.sort(dataComparator);
}
}
void test()
{
Tree<DataItem> tree = new Tree<>();
tree.sort( Comparator.comparing(DataItem::getName) );
}