簡體   English   中英

在遞歸通用數據結構中對對象進行排序

[英]Sorting objects in a recursive generic data structure

我有一個通用樹類,其中每個樹節點都包含一些數據。 每個數據都有一個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();
        }
    }
}

我有不同的想法來解決這個問題:

  • 使用反射來訪問對象的屬性並進行比較。
  • 在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()); } 

什么是正確或最好的事情? 還有其他方法嗎?

能夠指定排序屬性可能很重要。

我認為直接在Tree上使用Collections.sort()會很好,但在這個遞歸數據結構中實現它真的讓我很困惑。 這樣做的一個缺點是我無法指定排序屬性。

嘗試這個:

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之外,您還可以檢查其他類型參數。

    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) );
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM