将ArrayList分组为JSON数组/对象

时间:2018-05-24 14:44:55

标签: java json arraylist multidimensional-array

我在数据库中有一个文件结构,路径和文件名为列,并希望将它们组合在一起,但不知道如何做到这一点。这是我目前正在使用的精简版:

//in this example, list is the returned data
JSONArray jList1 = new JSONArray();
for (int a = 0; a < list.size(); a++){
    Object[] fileObj = (Object[])list.get(a);
    String folder = (String)fileObj[0];
    String filename = (String)fileObj[1];
    JSONObject jObj1 = new JSONObject();
    jObj1.put("path",folder);
    jObj1.put("filename",filename);
    jList1.add(jObj1);
}
response.getWriter().write(jList1.toJSONString());

这会将所有内容放入相同的JSONArray中。以下是输出的示例:

[
    {
        path: "/a",
        filename: ""
    },
    {
        path: "/a",
        filename: "file1.png"
    },
    {
        path: "/a/b",
        filename: ""
    },
    {
        path: "/a/b",
        filename: "file2.png"
    },
    {
        path: "/a/b",
        filename: "file3.png"
    },
    {
        path: "/a/c",
        filename: ""
    },
    {
        path: "/a/c",
        filename: "file4.jpg",
    },
    {
        path: "/",
        filename: "file5.jpg",
    },
    {
        path: "/",
        filename: "file6.jpg",
    }
]

我想拥有它:

[
    {
        path: "/a",
        filename: ""
        files: [
            {
                path: "/a/b",
                filename: ""
                files: [
                    {
                        path: "/a/b",
                        filename: "file2.png"
                    },
                    {

                        path: "/a/b",
                        filename: "file3.png"
                    }
                ]
            },          
            {
                path: "/a/c",
                filename: ""
                files: [
                    {
                        path: "/a/c",
                        filename: "file4.jpg",
                    }
                ]
            },
            {
                path: "/a",
                filename: "file1.png"
            }
        ]
    },
    {
        path: "/",
        filename: "file5.jpg",
    },
    {
        path: "/",
        filename: "file6.jpg",
    }
]

现在我可以知道确切的级别数,但不知道如何处理未知数量的树级别。我在示例中为每个对象提供了其他属性,这就是为什么我不只是将文件名本身放在数组中。

我遗漏了数据库结构,因为我们认为它确实不需要。唯一可能是它的订购方式,我有:

order by (CASE WHEN path='/' THEN 1 ELSE 0 END), path, filename

基本上每个级别的文件夹位于顶部,文件位于底部。

有人能让我按照我正在寻找的方式构建JSON吗?我知道它必须是某种存储记录,与以前的记录相比,但似乎无法弄清楚如何构建它。我曾考虑过对每个目录进行不同的查询,但这会导致很多数据库命中,从而导致性能问题。

2 个答案:

答案 0 :(得分:0)

我有建议尝试解决您的问题。

首先创建一个文件来存储每个文件/目录的值。这是一个例子:

import java.util.ArrayList;
import java.util.List;

public class Archive implements Comparable<Archive> {

    private String path;
    private String filename;
    List<Archive> files;

    public Archive(String path, String filename) {
        this.path = path;
        this.filename = filename;
        this.files = new ArrayList<Archive>();
    }

    public String getPath() {
        return path;
    }

    public String getFilename() {
        return filename;
    }

    public List<Archive> getFiles() {
        return files;
    }

    @Override
    public String toString() {
        return "Path = "+ path + ", Filename = "+ filename;
    }

    @Override
    public int compareTo(Archive archive) {
        return getPath().compareTo(archive.getPath());
    }

}

现在让我们创建一个读取文件夹并创建Archive类列表的方法:

public static void listFilesFromFolder(final File folder, final List<Archive> listArchive) {
    for (File file : folder.listFiles()) {
        if (file.isFile()) {
            String path = file.getPath().replace(mainFolderPath, "").replace(file.getName(), "");
            Archive archive = new Archive(path, file.getName());
            listArchive.add(archive);
        }
    }

    for (File file : folder.listFiles()) {
        if (file.isDirectory()) {
            String path = file.getPath().replace(mainFolderPath, "");
            Archive archive = new Archive(path, "");
            listArchive.add(archive);
            listFilesFromFolder(file, archive.getFiles());
        }
    }
}

接下来,我们将创建将List转换为JSON的方法。

public static String listToJSON(List<Archive> listArchive) {
    ObjectMapper mapper = new ObjectMapper();
    try {
        return mapper.writeValueAsString(listArchive);
    } catch (JsonGenerationException e) {
        e.printStackTrace();
    } catch (JsonMappingException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }

    return "";
}

最后我们将创建Main方法来运行我们的应用程序:

public class Test {

    final static String mainFolderPath = "c:\\MyFolder";

    public static void main(String[] args) {
        File folder = new File(mainFolderPath);

        List<Archive> listArchive = new ArrayList<Archive>();

        listFilesFromFolder(folder, listArchive);

        Collections.sort(listArchive);

        System.out.println( listToJSON(listArchive) );
    }
}

仅供参考,请按照使用的导入进行操作:

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.codehaus.jackson.JsonGenerationException;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper;

我希望我能帮到你。

答案 1 :(得分:0)

我最后通过创建ResourceTree类来实现这一点:

public class ResourceTree {
    private String parentPath;
    private List<ResourceTree> childrenItems;
    private JSONObject jObj1;

    public ResourceTree() {
        this.parentPath = "";
        this.childrenItems = new ArrayList<ResourceTree>();
    }

    public String getParentPath() {
        return parentPath;
    }

    public void setParentPath(String parentPath) {
        this.parentPath = parentPath;
    }

    public JSONObject getResourceObj() {
        return jObj1;
    }

    public void setResourceObj(JSONObject jObj1) {
        this.jObj1 = jObj1;
    }

    public List<ResourceTree> getChildrenItems() {
        return childrenItems;
    }

    public void setChildrenItems(List<ResourceTree> childrenItems) {
        this.childrenItems = childrenItems;
    }

    public void addChildrenItem(ResourceTree childrenItem){
        if(!this.childrenItems.contains(childrenItem))
            this.childrenItems.add(childrenItem);
    }

    public JSONArray getFileList() {
        JSONArray jList1 = new JSONArray();
        JSONObject jObj2 = new JSONObject();
        List rtChilds = getChildrenItems();
        for (int i = 0; i < rtChilds.size(); i++) {
            ResourceTree rt = (ResourceTree)rtChilds.get(i);
            jObj2 = rt.getResourceObj();
            if (rt.getChildrenItems().size() > 0) {
                jObj2.put("files",rt.getFileList());
            }
            jList1.add(jObj2);
        }
        return jList1;
    }
}

从那里,我为每个项目创建一个ResourceTree,并添加到适用的子项目中。

//list is an ArrayList of objects
if (list != null && list.size() > 0) {
    Map<String, ResourceTree> hm = new LinkedHashMap();
    for (int b = 0; b < list.size(); b++){
        Object[] fileObj = (Object[])list.get(b);
        if (fileObj != null) {
            String folder = (String)fileObj[0];
            String parentFolder = folder;
            String fn = (String)fileObj[1];
            String type = "";
            if (fn.equals("")) {
                parentFolder = folder.substring(0,folder.lastIndexOf("/"));
            }
            jObj1 = new JSONObject();
            jObj1.put("path",folder);
            jObj1.put("filename",fn);   

            ResourceTree rt = new ResourceTree();
            rt.setResourceObj(jObj1);
            rt.setParentPath(parentFolder);
            if (fn.equals("")) {
                hm.put(folder,rt);
            }
            ResourceTree rtParent;
            if (hm.containsKey(parentFolder)){
                rtParent = hm.get(parentFolder);
            } else {
                rtParent = new ResourceTree();
                rtParent.setParentPath(parentFolder.substring(0,parentFolder.lastIndexOf("/")));
                hm.put(parentFolder,rtParent);
            }
            rtParent.addChildrenItem(rt);
        }
    }
    List<ResourceTree> DX = new ArrayList<ResourceTree>();
        for (ResourceTree rt : hm.values()) {
            //path is the top level folder specified
            if (rt.getParentPath().equals(path.substring(0,path.lastIndexOf("/")))) {
                jList1.addAll(rt.getFileList());
            }
        }
    }
}