0

その件については申し訳ありませんが、より良いタイトルが見つかりませんでした:-)

私はツリー構造を持っています。ここに私の「ノード」クラスがあります:

public class Categoria implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @NotNull
    private String name;

    @OneToMany(cascade=CascadeType.ALL,fetch=FetchType.EAGER)
    @JoinColumn(name = "parent_id")
    private List<Categoria> children = new LinkedList<Categoria>();

    @ManyToOne(fetch=FetchType.LAZY)
    @JoinColumn(
        name = "parent_id",
        insertable=false,
        updatable=false
    )
    private Categoria parent;

    @Transient
    private Integer depth;

    private Integer orderNumber;

... getters, setters, ....
}

Hibernate/JPA アノテーションを気にする必要はありません。問題はありません。理想的な pojo の世界を考えてみてください。

隣接するノードの「プレーンな」リストを作成する再帰的な方法を作成しました。だから、この木を想像してください:

grandfather

 |_ father

    |_ son1

    |_ son2

 |_ uncle

grandmother

 |_ mother

次のようなリストが得られます (数字は「深さ」です): - 祖父 (1) - 父 (2) - 息子 1 (3) - 息子 2 (3) - 叔父 (2) - 祖母 (1) - 母 ( 2)

すべてうまくいきます。

ここで、ユーザーがノードの並べ替えを (同じ深さのノード間で) 編集できるようにしたいと考えています。つまり、上記のリストで「son1」の前に「son2」が必要な場合はどうすればよいでしょうか?

そこで、「orderNumber」プロパティを追加することにしました。最初はすべての orderNumbers が 0 です。次に、ユーザーは son1 の orderNumber を 99 に、son2 の orderNumber を 88 に設定しました。

問題は、結果のリストを並べ替えて、orderNumber に基づいて並べ替えるにはどうすればよいかということです。

しかし、待ってください....「サブリスト」のみをソートしたいので、息子のソートは「父」や「叔父」のソートとはまったく関係ありません!

助けてくれてありがとう。

編集:あなたはすべて1つのことを見逃しています. 私は自分自身をうまく説明できませんでした。次に例を示します。

  • おじいさん (深さ:1、順序番号:1)
  • 父 (深さ:2、順序番号:1)
  • son1 (深さ:3、順序番号:1)
  • son2 (深さ:3、順序番号:2)
  • おじさん (深さ:2、注文番号:2)
  • おばあさん (深さ:1、順番:2)
  • マザー (深さ:2、順序番号:1)

ここで、son1 と son2 を入れ替えたいので、結果のリストは次のようになります。

  • おじいさん (深さ:1、順序番号:1)
  • 父 (深さ:2、順序番号:1)
  • son2 (深さ:3、順序番号:1)
  • son1 (深さ:3、順序番号:2)
  • おじさん (深さ:2、注文番号:2)
  • おばあさん (深さ:1、順番:2)
  • マザー (深さ:2、順序番号:1)

そのような目的で sort / compareTo を実装するにはどうすればよいですか??

4

4 に答える 4

2

CategoriaにComparableを実装させます。カスタムの compareTo 実装を作成します。この実装では、深さによって並べ替え、追加の OrderNumber 属性によって決定されます。これは、ソート可能なコレクションで機能します。

しかし、そのツリー構造で解決しようとしている問題によっては、「リスト スナップショット」を再帰的に作成する代わりに、ツリーにカスタム イテレータを実装する方が適している場合があります。

于 2012-06-08T10:06:59.020 に答える
1

私はあなたのクラスに実装Comparableを作成し、compareToメソッドではフィールドを使用depthorderNumberて順序を計算します。これが完了したら、Collectoins.sort()を使用してリストを並べ替えることができます。

コード例:

public class Categoria implements Serializable, Comparable<Categoria> {

    private static final long serialVersionUID = 1L;

    // ... omitting other fields/annotations/getters/setters

    private Integer depth;

    private Integer orderNumber;

    @Override
    public int compareTo(Categoria other) {
        if (depth < other.depth)
            return -1;
        if (depth > other.depth)
            return 1;
        // if we get here the two objects have the same depth, so we compare 
        // based on orderNumber
        if (orderNumber < other.orderNumber)
            return -1;
        if (orderNumber > other.orderNumber)
            return 1;
        return 0;
    }

}
于 2012-06-08T12:59:47.033 に答える
1

Collections.sort() と適切なコンパレータで明示的にサブリストをソートできます。

リストを作成するときに並べ替えがわかっている場合は、LinkedList の代わりに TreeSet のような順序付きセットをコンパレータと共に使用できます。そのため、アイテムは挿入時にソートされます。

于 2012-06-08T10:08:27.880 に答える
0

私はそれが必要でした:

private List<Categoria> getAlberoCategorie(Categoria root, int profondita) {
        List<Categoria> tmpList = new ArrayList<Categoria>();
        root.setProfondita(profondita);
        if ( root.getParent() != null ) {
            Hibernate.initialize(root.getTraduzioni());
            tmpList.add(root);
        }       

        List<Categoria> children = root.getChildren();
        Collections.sort(children, new Comparator<Categoria>() {
            @Override
            public int compare(Categoria o1, Categoria o2) {
                return o1.getOrdinamento().compareTo(o2.getOrdinamento());
            }
        });

        if (!children.isEmpty()) {
            profondita++;
            for (Categoria figlia : children) {
                List<Categoria> discendenza = getAlberoCategorie(figlia,profondita);                
                tmpList.addAll(discendenza);
            }
        }       
        return tmpList;
    }

とにかくありがとう!

于 2012-06-11T06:56:27.930 に答える