Comment Redresser une hiérarchie aplani avec des API de flux

Sam:

Si j'ai une structure hiérarchique qui est encore triée, mais aplatis - comment puis-je créer une structure parent / enfant avec l'API Java Streams? Un exemple: Comment puis-je de

-,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

Une façon simple non-stream serait de garder une trace de la colonne mère et de voir si elle a changé.

J'ai essayé de diverses manières avec les collectionneurs et groupingBy, mais pas encore trouvé comment faire.

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(???))
Ils étaient les suivants:

Vous pouvez créer un Mapde chaque Rowindexé par le nom de ce:

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

getName()étant la deuxième propriété transmise au Rowconstructeur.

Maintenant , vous pouvez l' utiliser Mappour construire l'arbre:

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

getParent()étant la première propriété a été transférée au Rowconstructeur.

Cela nécessiterait la Rowclasse de passer outre equalset hashCodecorrectement, de sorte que deux Rowcas seront considérés comme égaux si elles ont le même nom.

Vous devriez probablement ajouter une racine Rowà votre entrée Listbien. Quelque chose comme:

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

ÉDITER:

Je l' ai testé avec une pleine Rowclasse (si je fait quelques raccourcis), y compris un exemple de traverser l'arbre de la racine le long du premier enfant de chaque niveau:

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

Production:

L'arbre:

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

Le parcours:

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

Je suppose que tu aimes

Origine http://43.154.161.224:23101/article/api/json?id=238847&siteId=1
conseillé
Classement