【问题标题】:java convert flat array structure to hirerarchicaljava将平面数组结构转换为分层结构
【发布时间】:2018-05-23 07:37:13
【问题描述】:

我有以下值对象的 java 数组,格式如下

[
{grandParent1,parent1,child1},
{grandParent1,parent1,child2},
{grandParent1,parent2,child3},
{grandParent2,parent1,child4},
{grandParent2,parent2,child5},
{grandParent2,parent3,child6},
]

需要转换成如下的层次结构

{
  grandParent1
  {
     parent1
     {
         child1{
         },
         child2{
         }
     },
       parent2
     {
         child3{
         } 
     }
   },

   grandParent2
  {
     parent1
     {
         child4{
         } 
     },
      parent2
     {
         child5{
         } 
     },
     parent3
     {
         child6{
         } 
     }
   }
} 

我们有对象类的平面结构值,具有如下属性。

 public class TestVO {
    private String grandParent;

    private String parent;

    private String child;

    public String getGrandParent() {
        return grandParent;
    }

    public void setGrandParent(String grandParent) {
        this.grandParent = grandParent;
    }

    public String getParent() {
        return parent;
    }

    public void setParent(String parent) {
        this.parent = parent;
    }

    public String getChild() {
        return child;
    }

    public void setChild(String child) {
        this.child = child;
    }

}

请提出一些高效且性能更好的逻辑,以将 java 对象中的平面结构转换为层次结构。

更新 我在每个祖父母、父母和孩子级别都有更多的字段。我们可以在逻辑中使用它吗?请找到以下更新对象的简短形式。这里的 grandParentId、parentId 和 childId 在每个级别都是唯一的。

public class TestVO {
private String grandParentId;
private String grandParentFirstName;
private String grandParentLastName;
private String parentId;
private String parentFirstName;
private String parentLastName;
private String childId;
private String childFirstName;
private String childLastName;
}

【问题讨论】:

    标签: java arrays algorithm object data-structures


    【解决方案1】:

    您可以将 Java 8 Streams 与 groupingBy 收集器一起使用:

    List<TestVO> list = ...
    Map<String,Map<String,List<String>>>
        map = list.stream()
                  .collect(Collectors.groupingBy(TestVO::getGrandParent,
                                                 Collectors.groupingBy(TestVO::getParent,
                                                                       Collectors.mapping(TestVO::getChild, 
                                                                                          Collectors.toList()))));
    

    这将创建一个Map,其键是祖父母,其值是内部Maps,其中键是父母,值是相应的孩子。

    至于您更新的问题,我建议您为层次结构的每个级别创建一个类 - GrandParentParentChild。每个类将包含相应的 3 个属性。现在,如果您将TestVO 更改为包含GrandParent 实例、Parent 实例和Child 实例而不是9 个属性,则可以使用与上述相同的代码生成Map&lt;GrandParent,Map&lt;Parent,List&lt;Child&gt;&gt;&gt;。您必须在 GrandParentParent 类中覆盖 equals()hashCode()

    如果您无法按照建议更改输入对象,您可以将map() 步骤添加到上述Stream 管道(在collect() 步骤之前),将TestVO 实例转换为一些新的类实例包含GrandParentParentChild

    【讨论】:

    • 感谢您的帮助,但实际情况不同意味着我在每个祖父母、父母和孩子级别都有更多的字段。我们可以在逻辑中使用它吗?请找到以下更新对象的简短形式。这里的 ID 将是唯一的。公共类 TestVO { 私有字符串 grandParentId;私人字符串 grandParentFirstName;私人字符串 grandParentLastName;私有字符串父ID;私有字符串父名字;私有字符串 parentLastName;私有字符串 childId;私人字符串 childFirstName;私人字符串 childLastName; }
    • Eran,谢谢你的帮助。我不能改变输入,所以尝试第二种方式。我以分层方式创建了新类 TestHierarchy>TestGrandParent->TestParent->TestChild 我添加了如下图。 .map(测试层次结构)。它显示错误 map = list.stream() .map(TestHierarchy) .collect(.... 请你帮忙如何添加地图
    • 有没有办法而不是字符串将它用于对象
    • @sardarCoder 创建一个包含 GrandParent 实例、Parent 实例和 Child 实例的类(我们称之为 TestClasses),为该类定义一个接受 TestVO 对象的构造函数,然后在collect 之前添加一个map(TestClasses::new) 步骤。
    • 我按照你的建议添加了,但它给了我以下错误 Stream 类型中的方法 collect(Collector super TestHierarchy,A,R>) 不适用于参数 (Collector>>>) 我创建了具有以下属性的 TestHierarchy 类 private TestGrandParent testGrandParent;私人TestParent testParent;私人TestChild testChild;
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多