ストリームAPIで平坦化された階層を非平坦化する方法

サム:

私はまだソートされている階層構造を持っていますが、平坦化されている場合 - どのように私はJavaストリームAPIを持つ親/子構造を作成することができますか?例:どのように私はから行くのですか

-,A,Foo
A,A1,Alpha1
A,A2,Alpha2
-,B,Bar
B,B1,Bravo1
B,B2,Bravo2

-
  A
    A1,Alpha1
    A2,Alpha2
  B
    B1,Bravo1
    B2,Bravo2

シンプルな非ストリームの方法は、親列を追跡し、それが変更されているかどうかを確認することです。

私はコレクターとgroupingByでさまざまな方法を試してみましたが、まだ実行する方法を発見していません。

List<Row> list = new ArrayList<>();
list.add(new Row("-", "A", "Root"));
list.add(new Row("A", "A1", "Alpha 1"));
list.add(new Row("A", "A2", "Alpha 2"));
list.add(new Row("-", "B", "Root"));
list.add(new Row("B", "B1", "Bravo 1"));
list.add(new Row("B", "B2", "Bravo 2"));

//Edit
Map<Row, List<Row>> tree;

tree = list.stream().collect(Collectors.groupingBy(???))
彼らは次のとおりでした:

あなたは、作成することができMap、それぞれのRowそれの名をインデックスを:

Map<String,Row> nodes = list.stream().collect(Collectors.toMap(Row::getName,Function.identity()));

getName()渡された第二の特性であることRowのコンストラクタ。

今、あなたはそれを使用することができますMapツリーを構築します:

Map<Row,List<Row>> tree = list.stream().collect(Collectors.groupingBy(r->nodes.get(r.getParent())));

getParent()渡された最初のプロパティであることRowのコンストラクタ。

これが必要になりRow上書きするクラスをequalsし、hashCode2つのだから、きちんとRow彼らは同じ名前を持っている場合、インスタンスが等しいと見なされます。

おそらく、ルートを追加する必要がありRow、あなたの入力にListかかわらず。何かのようなもの:

list.add(new Row(null, "-", "Root"));

EDIT:

私はフルでそれをテストしRow、各レベルの最初の子に沿ってルートからツリーを横断する例を含め、(私はいくつかのショートカットを作ったが)クラス:

class Row {
    String name;
    String parent;
    Row (String parent,String name,String something) {
        this.parent = parent;
        this.name = name;
    }
    public String getParent () {return parent;}
    public String getName () {return name;}

    public int hashCode () {return name.hashCode ();}
    public boolean equals (Object other) {
        return ((Row) other).name.equals (name);
    }
    public String toString ()
    {
        return name;
    }

    public static void main (String[] args)
    {
        List<Row> list = new ArrayList<>();
        list.add(new Row(null, "-", "Root"));
        list.add(new Row("-", "A", "Root"));
        list.add(new Row("A", "A1", "Alpha 1"));
        list.add(new Row("A1", "A11", "Alpha 11"));
        list.add(new Row("A", "A2", "Alpha 2"));
        list.add(new Row("-", "B", "Root"));
        list.add(new Row("B", "B1", "Bravo 1"));
        list.add(new Row("B", "B2", "Bravo 2"));
        Map<String,Row> nodes = 
            list.stream()
                .collect(Collectors.toMap(Row::getName,Function.identity()));
        Map<Row,List<Row>> tree = 
            list.stream()
                .filter(r->r.getParent()!= null)
                .collect(Collectors.groupingBy(r->nodes.get(r.getParent())));
        System.out.println (tree);
        Row root = nodes.get ("-");
        while (root != null) {
            System.out.print (root + " -> ");
            List<Row> children = tree.get (root);
            if (children != null && !children.isEmpty ()) {
                root = children.get (0);
            } else {
                root = null;
            }
        }
        System.out.println ();
    }
}

出力:

ツリー:

{A1=[A11], A=[A1, A2], B=[B1, B2], -=[A, B]}

トラバーサル:

- -> A -> A1 -> A11 -> 

おすすめ

転載: http://43.154.161.224:23101/article/api/json?id=238846&siteId=1