如何使用Streams API展开扁平化的层次结构 [英] How to unflatten a flattened hierarchy with Streams API

查看:89
本文介绍了如何使用Streams API展开扁平化的层次结构的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我的层次结构仍在排序但变平了-如何使用Java Streams API创建父/子结构?一个例子: 我怎么走

If I have a hierarchical structure that is still sorted, but flattened - how can I create a parent/child structure with Java Streams API? An example: How do I go from

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

一种简单的非流式方法是跟踪父列并查看其是否已更改.

A simple non-stream way would be to keep track of the parent column and see if it has changed.

我已经尝试过使用Collector和groupingBy的各种方法,但是还没有找到方法.

I have tried various ways with Collectors and groupingBy, but have not yet found how to do.

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(???))

推荐答案

您可以为每个以其名称索引的Row创建一个Map:

You could create a Map of each Row indexed by it's name:

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

getName()是传递给Row构造函数的第二个属性.

getName() being the second property passed to the Row constructor.

现在,您可以使用该Map来构建树:

Now you can use that Map to build the tree:

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

getParent()是传递给Row构造函数的第一个属性.

getParent() being the first property passed to the Row constructor.

这将要求Row类正确覆盖equalshashCode,以便两个具有相同名称的Row实例被视为相等.

This would require the Row class to override equals and hashCode properly, so that two Row instances will be considered equal if they have the same name.

您可能应该将根Row添加到输入List中.像这样:

You should probably add a root Row to your input List though. Something like:

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

我使用完整的Row类对其进行了测试(尽管我做了一些捷径),其中包括一个从树根遍历每个级别的第一个孩子的示例:

I tested it with a full Row class (though I made some shortcuts), including an example of traversing the tree from the root along the first child of each level:

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

这篇关于如何使用Streams API展开扁平化的层次结构的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆