首页 > 解决方案 > java将平面数组结构转换为分层结构

问题描述

我有以下值对象的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;
}

标签: javaarraysalgorithmobjectdata-structures

解决方案


您可以将 Java 8StreamgroupingBy收集器一起使用:

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,其中键是父母,值是相应的孩子。

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

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


推荐阅读