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(???))
Vous pouvez créer un Map
de chaque Row
indexé 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 Row
constructeur.
Maintenant , vous pouvez l' utiliser Map
pour 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 Row
constructeur.
Cela nécessiterait la Row
classe de passer outre equals
et hashCode
correctement, de sorte que deux Row
cas seront considérés comme égaux si elles ont le même nom.
Vous devriez probablement ajouter une racine Row
à votre entrée List
bien. Quelque chose comme:
list.add(new Row(null, "-", "Root"));
ÉDITER:
Je l' ai testé avec une pleine Row
classe (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 ->