如何获得所需的结果,结果是数组列表?

时间:2017-11-04 05:31:23

标签: java

我有一个对象数组,基本上是一个Arraylist。 输入和输出数据如下所示

A little love (2002)
No.1 Star
Love Story

如果任何对象的父级等于id,那么这将成为结果看起来像这样的子级。

 data=  [
      {
        id:1,
        parent:0
      },
       {
        id:2,
        parent:0
      },

       {
        id:3,
        parent:1
      },
       {
        id:4,
        parent:1
      },
       {
        id:5,
        parent:3
      },
       {
        id:6,
        parent:3
      }
    ]

因为我无法通过使用for循环访问对象数组的内部元素,所以我无法在其上放置条件。 我尝试使用这样的东西

    [
      {
        id:1,
        parent:0,
        children:[
                  {
                    id:3,
                    parent:1,
                    children:[ {
                                id:5,
                                parent:3
                               },
                               {
                                id:6,
                                parent:3
                                }
                              ]
                    },
                   {
                    id:4,
                    parent:1
                  }
          ]
      },
       {
        id:2,
        parent:0
      }

    ]

怎么做?

我的完整代码:

for(Map <String,Object> individual_object: data) {

}

4 个答案:

答案 0 :(得分:1)

为什么不用以下字段定义Class(让我们将此类名定义为ParentChildClass

public class ParentChildClass{
    int id;
    ParentChildClass parent;
    ArrayList<ParentChildClass> children;
    ParentChildClass(ParentChildClass parent){
        this.children = new ArrayList<ParentChildClass>();
        if(parent != null){
            this.parent  = parent;
        }
    }
    //getter and setters

    //method to add a child
    public void addChild(ParentChildClass child){
        children.add(child);
    }
}

现在将其包装在HashMap<Integer, ParentChildClass>内,以便通过其ID轻松访问所有元素。迭代您当前拥有的object,然后通过创建HashMap的实例,在ParentChildClass中逐个添加这些元素。如果父项已经不存在于HashMap中,找到具有父项id的元素,则通过创建新实例将其包含在HashMap中(不要现在递归添加父项,因为您将无论如何,在迭代时稍后会出现此元素,此时您也可以为此对象添加父元素。完成此操作后,将新创建的父元素设置为Child元素的父元素,然后继续。

最后,您将留下一个地图,该地图引用了所有父子对象,可用于访问O(1)及其父级及其所有子级(在arraylist中)中的元素。

答案 1 :(得分:1)

您可以通过首先将元素循环并将其ID收集到地图来将元素连接到父元素。这将允许您在再次循环它们之后为每个元素找到父元素,以构建您描述的层次结构。请注意,您还需要收集没有父项的元素(在下面称为根。

List<MyElement> list = asList(
        new MyElement(1, 0),
        new MyElement(2, 0),
        new MyElement(3, 1),
        new MyElement(4, 1),
        new MyElement(5, 3),
        new MyElement(6, 3));

Map<Integer, MyElement> elementsById = new HashMap<>();
for (MyElement element : list) {
    elementsById.put(element.getId(), element);
}

List<MyElement> roots = new ArrayList<>();
for (MyElement element : elementsById.values()) {
    if (elementsById.containsKey(element.getParent())) {
        MyElement parent = elementsById.get(element.getParent());
        parent.addChild(element);
    } else {
        roots.add(element);
    }
}

System.out.println(roots);

MyElement类供参考

public class MyElement {
    private int id;
    private int parent;
    private List<MyElement> children = new ArrayList<>();

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

    @Override
    public String toString() {
        return "{id=" + id + ", children=" + children + "}";
    }

    public void addChild(MyElement child) {
        if (child.parent != id) {
            throw new IllegalArgumentException("Expected parent id " + id + " got " + child.parent);
        }
        children.add(child);
    }

    public int getId() {
        return id;
    }

    public int getParent() {
        return parent;
    }

    public List<MyElement> getChildren() {
        return Collections.unmodifiableList(children);
    }
}

答案 2 :(得分:1)

首先,您需要一个Item类来存储id和父ID:

(toString()用于调试,因此您可以打印输入和输出列表以验证结果)

public class Item {
    private final int parentId;
    private final int id;

    private final java.util.List<Item> children = new ArrayList<>();

    public Item(int parentId, int id) {
        this.parentId = parentId;
        this.id = id;
    }

    public void addChild(Item child) {
        children.add(child);
    }

    @Override
    public String toString() {
        String result = "id: " + id + ", parent: " + parentId;

        if (children.isEmpty() == false) {
            result += ", children: " + children;
        }

        return result;
    }

    public int getId() {
        return id;
    }

    public int getParentId() {
        return parentId;
    }
}

然后像往常一样,准备输入并处理它的Main类和main方法:

public class Main {
    public static void main(String[] args) {
        java.util.List<Item> inputItems = createInputItems();
        java.util.List<Item> oututItems = processItemsToParentChildren(inputItems);

        System.out.println(oututItems);     
    }

创建输入法很简单:

private static List<Item> createInputItems() {
    java.util.List<Item> result = new ArrayList<>();


    result.add(new Item(0, 1));
    result.add(new Item(0, 2));

    result.add(new Item(1, 3));
    result.add(new Item(1, 4));

    result.add(new Item(3, 5));
    result.add(new Item(3, 6));

    return result;
}

然后你需要一个方法将id映射到相应的项目:

private static Map<Integer, Item> prepareIdItemMap(List<Item> items) {
    HashMap<Integer, Item> result = new HashMap<>();

    for (Item eachItem : items) {
        result.put(Integer.valueOf(eachItem.getId()), eachItem);
    }

    return result;
}

然后关键部分,将正确的子项添加到其父项,或者如果父项id为0,则添加到列表的根目录:

private static List<Item> processItemsToParentChildren(List<Item> items) {
    java.util.List<Item> result = new ArrayList<>();

    Map<Integer, Item> idItemMap = prepareIdItemMap(items);

    for (Item eachItem : items) {
        int parentId = eachItem.getParentId();

        if (parentId == 0) {
            result.add(eachItem);
        } else {
            idItemMap.get(Integer.valueOf(parentId)).addChild(eachItem);
        }
    }


        return result;
    }

答案 3 :(得分:0)

如果对象的内部字段为private,则无法按名称访问它们。 你不能写object.field

您需要拥有访问权限来获取其值

您的代码将为object.getFiled()