Java 需要根据父子关系将数据列表转换为列表列表

Java 需要根据父子关系将数据列表转换为列表列表,java,Java,我需要根据父子关系将数据列表转换为列表列表。如果父项为空,则属于级别1,级别2将基于级别1 id 我的数据如下所示: [ {id:1, parent: null }, {id:2, parent: 1 }, {id:3, parent: 1 }, {id:4, parent: 1 }, {id:5, parent: 2 }, {id:6, parent: 2 }, {id:7, parent: 3 }, {id:8, parent:

我需要根据父子关系将数据列表转换为列表列表。如果父项为空,则属于级别1,级别2将基于级别1 id

我的数据如下所示:

[
    {id:1, parent: null },
    {id:2, parent: 1 },
    {id:3, parent: 1 },
    {id:4, parent: 1 },
    {id:5, parent: 2 },
    {id:6, parent: 2 },
    {id:7, parent: 3 },
    {id:8, parent: 3 },
    {id:9, parent: 4 },
    {id:10, parent: 4 },
    {id:11, parent: 5 },
    {id:12, parent: null },
    {id:13, parent: 12 },
]
First level array contains the data where parent is null

Second level contains the children of level 1 ie id 2,3,4 are a child of id 1

Third level contains the children of levlel2 objects ie 5 & 6 are a child of 2 , 7 & 8 are a child of 3 and 9 & 10 child of 4

Level four contains the children of level 3 objects ie 11 is a child of id 5

[
    [ {id:1, parent: null }, {id:12, parent:null} ],
    [ {id:2, parent: 1 },{id:3, parent: 1 },{id:4, parent: 1 },{id:13, parent: 12 } ],
    [ {id:5, parent: 2 },{id:6, parent: 2 },{id:7, parent: 3 },{id:8, parent: 3 },{id:9, parent: 4 },{id:10, parent: 4 } ],
    [ {id:11, parent: 5 }]
]
我的代码是:

响应数据

Map<String,Map<String,ResponseData>> map = new HashMap<>();
for (ResponseData responseData : responseDataList) {
    Map<String,responseData> responseDatasMap =  map.get(responseData.getParent());
    if(responseDatasMap != null) {
        responseDatasMap.put(responseData.getId(),responseData);
        map.put(responseData.getParent(),responseDatasMap);
    } else {
        responseDatasMap =  new HashMap<>();
        responseDatasMap.put(responseData.getParent(),responseData);
        map.put(responseData.getParent(),responseDatasMap);
    }
}
但我的预期输出要求如下:

[
    {id:1, parent: null },
    {id:2, parent: 1 },
    {id:3, parent: 1 },
    {id:4, parent: 1 },
    {id:5, parent: 2 },
    {id:6, parent: 2 },
    {id:7, parent: 3 },
    {id:8, parent: 3 },
    {id:9, parent: 4 },
    {id:10, parent: 4 },
    {id:11, parent: 5 },
    {id:12, parent: null },
    {id:13, parent: 12 },
]
First level array contains the data where parent is null

Second level contains the children of level 1 ie id 2,3,4 are a child of id 1

Third level contains the children of levlel2 objects ie 5 & 6 are a child of 2 , 7 & 8 are a child of 3 and 9 & 10 child of 4

Level four contains the children of level 3 objects ie 11 is a child of id 5

[
    [ {id:1, parent: null }, {id:12, parent:null} ],
    [ {id:2, parent: 1 },{id:3, parent: 1 },{id:4, parent: 1 },{id:13, parent: 12 } ],
    [ {id:5, parent: 2 },{id:6, parent: 2 },{id:7, parent: 3 },{id:8, parent: 3 },{id:9, parent: 4 },{id:10, parent: 4 } ],
    [ {id:11, parent: 5 }]
]

请检查并让我知道我们如何实现相同的功能。提前感谢表示树结构,我使用了
ArrayList
,其中节点的索引等于其在数组中的索引+1。如果您有一棵稀疏树/某些索引可能丢失,请使用与映射等效的方法

使用Java 8流API的解决方案:

public static void main( String[] args ) {
        List<ResponseData> responseDataList = Arrays.asList(
            new ResponseData( 1, -1 ),  // changed null to -1 as null can't be a map key
            new ResponseData( 2, 1 ),
            new ResponseData( 3, 1 ),
            new ResponseData( 4, 1 ),
            new ResponseData( 5, 2 ),
            new ResponseData( 6, 2 ),
            new ResponseData( 7, 3 ),
            new ResponseData( 8, 3 ),
            new ResponseData( 9, 4 ),
            new ResponseData( 10, 4 ),
            new ResponseData( 11, 5 ),
            new ResponseData( 12, -1 ),
            new ResponseData( 13, 12 )
        );
        final Map<Integer, List<ResponseData>> map = responseDataList.stream()
                .collect( Collectors.groupingBy( o -> getLevel( responseDataList, o, 0 ) ) );
        System.out.println( map );
        // To convert the Map to a List of Lists:
        System.out.println( new ArrayList<>( map.values() ));
    }

    private static int getLevel(List<ResponseData> nodes, ResponseData responseData, int level) {
        if( responseData.parent == -1 ) {
            return level;
        } else {
            return getLevel( nodes, nodes.get( responseData.parent - 1 ), level + 1 );  // -1 to adjust index
        }
    }

    private static final class ResponseData {
        public int id;
        public int parent;

        public ResponseData( int id, int parent ) {
            this.id = id;
            this.parent = parent;
        }

        @Override
        public String toString() {
            return String.format( "{id: %d, parent: %d}", id, parent );
        }
    }
publicstaticvoidmain(字符串[]args){
List responseDataList=Arrays.asList(
new ResponseData(1,-1),//将null更改为-1,因为null不能是映射键
新回应数据(2,1),
新答复数据(3,1),
新答复数据(4,1),
新回应数据(5,2),
新回应数据(6,2),
新回应数据(7,3),
新回应数据(8,3),
新回应数据(9,4),
新回应数据(10,4),
新回应数据(11,5),
新响应数据(12,-1),
新答复数据(13、12)
);
最终映射图=responseDataList.stream()
.collect(收集器.groupingBy(o->getLevel(responseDataList,o,0));
系统输出打印项次(map);
//要将地图转换为列表列表,请执行以下操作:
System.out.println(新的ArrayList(map.values());
}
私有静态int-getLevel(列表节点、响应数据、响应数据、int-level){
if(responseData.parent==-1){
回报水平;
}否则{
返回getLevel(nodes,nodes.get(responseData.parent-1),level+1);//-1以调整索引
}
}
私有静态最终类响应数据{
公共int id;
公共int家长;
公共响应数据(int-id,int-parent){
this.id=id;
this.parent=parent;
}
@凌驾
公共字符串toString(){
返回String.format(“{id:%d,父项:%d}”,id,父项);
}
}

此外,此代码期望您的树确实是一棵树。如果有任何循环,它将无限循环,最终导致堆栈溢出。

为什么不将其转换为流,并通过使用“Collectors.groupingBy(parent#getId,Collection#List)”保持简单?是的,groupingBy(parent#getId,Collection#List)将提供良好的可读性以及在UI中表示键、对值的干净json(只是一个建议)。一旦我的逻辑得到修复并开始按预期工作,我将把代码转换为流。感谢@emotionlessbananas的建议这将根据父项对数据进行分组,但我需要像我在问题中提到的那样形成列表列表。然后在获取密钥后,迭代映射,创建列表列表,并开始使用您获得的密钥对其进行筛选。这样做不需要太多的代码,而且代码要短得多,所以在我难以处理并且无法获得预期输出的情况下,可以这样做。此外,我的数据不会按顺序出现,我的顺序也会有所不同,因此您可以使用
新建ArrayList(map.values())
将地图转换为列表,我正在尝试为您添加赏金,但抛出的错误表明我可能在6小时后奖励赏金。6小时后我会给你赏金@昂德拉克。