假设在这种情况下我有这样的表/列表n = 3,但是n可以是无限制的。
groupid answerid1 answerid2 answerid(n)
1 3 6 8
1 3 6 9
1 4 7
2 5
我想使用java创建这样的父/子树json输出。(我一直在使用GSON)
{
data: [
{
groupid: 1,
children: [
{
answerid1: 1,
children: [
{
answerid2:3,
children: [
{
answerid3:6,
children: [
{answerid4: 8},
{answerid4: 9}
]
}
}, {
answerid2: 4,
children: [
{answerid3:7}
]
}
]
},
{
groupid1: 2,
children: [
{ answerid2: 5}
]
}
]
}
这样做的代码/步骤是什么。我查看了很多标签,但大多数人都在打印输出,而不是递归地为GSON构建一个hashmap / ArrayList来解析adn写入API。另一点每个id都有与之关联的其他数据,这些数据必须包含在json输出中。例如,而不是{groupid:1}需要这个{groupid:1,text = toyota}。
任何帮助都非常感谢,因为我来自SAS,因为我来自SAS背景。
我得到这样的数据(只是一个列表矩阵) 丰田,天然气,紧凑型,卡罗拉
如果需要,我可以将数据重新编入两个表格
parentId parText answerId
answerId level answerTextid answerText
然后我需要使它成为一个树(嵌套输出,如JSON显示父/子 - 就像你创建一个文件系统目录一样)
另一个我想做的是每辆车都有里程作为变种({answerid3:4,text =花冠,里程= 38}。但是如果我遍历树,给分支平均一英里就像在分公司丰田,Gas,Compact那样,里程将是平均值(凯美瑞,卡罗拉)输出有点偏,我正在寻找这样的东西。如果没有孩子那么没有孩子arraylist,并且attrbutes是一个对象(hashmap)的一部分
{"data":[{"id":1,"children":
[{"id": 2,"children":
[{"id": 3 ,"children":
[{"id": 4,"name":"Prius"}],"name":"Compact"}],"name":"Hybrid"},
{"id":5,"children":
[{"id":3,"children":
[{"id":7,"MPG":38, "name":"Corolla"},
{"id":8,"MPG":28,"name":"Camry"}],"name":"Compact"}],"name":"Gas"}],"name":"Toyota"},
{"id":9, "children":
[{"id":10,"children":
[{"id":3 ,"children":
[{"id":11 ,"name":"Civic"}],"name":"Compact"}],"name":"Gas"}],"name":"Honda"}]}
答案 0 :(得分:2)
您应该在所需的结构中创建用于建模数据的类。您基本上希望从某些基于行的数据构建层次结构,这非常类似于XML文档,这可能是一个合适的解决方案。但是你让我迷上了,所以我玩了之前我所拥有的并想出了这个:
public class Test {
public static void main(String[] args)
{
// hierarchical data in a flattened list
String[][] data = {
{"Toyota", "Gas", "Compact", "Corolla"},
{"Toyota", "Gas", "Compact", "Camry"},
{"Toyota", "Hybrid", "Compact", "Prius"},
{"Honda", "Gas", "Compact", "Civic"}
};
TreeManager treeManager = new TreeManager();
for(String[] row : data)
{
// build the path to our items in the tree
List<String> path = new ArrayList<String>();
for(String item : row)
{
// add this item to our path
path.add(item);
// will add it unless an Item with this name already exists at this path
treeManager.addData(treeManager, path);
}
}
treeManager.getData(data[0]).putValue("MPG", 38);
treeManager.getData(data[1]).putValue("MPG", 28);
Gson gson = new Gson();
System.out.println(gson.toJson(treeManager));
}
/**
* This base class provides the hierarchical property of
* an object that contains a Map of child objects of the same type.
* It also has a field - Name
*
*/
public static abstract class TreeItem implements Iterable<TreeItem>{
private Map<String, TreeItem> children;
private String name;
public TreeItem() {
children = new HashMap<String, TreeItem>();
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void addChild(String key, TreeItem data)
{
children.put(key, data);
}
public TreeItem getChild(String key)
{
return children.get(key);
}
public boolean hasChild(String key)
{
return children.containsKey(key);
}
@Override
public Iterator<TreeItem> iterator() {
return children.values().iterator();
}
}
/**
* This is our special case, root node. It is a TreeItem in itself
* but contains methods for building and retrieving items from our tree
*
*/
public static class TreeManager extends TreeItem
{
/**
* Will add an Item to the tree at the specified path with the value
* equal to the last item in the path, unless that Item already exists
*/
public void addData(List<String> path)
{
addData(this, path);
}
private void addData(TreeItem parent, List<String> path)
{
// if we're at the end of the path - create a node
String data = path.get(0);
if(path.size() == 1)
{
// unless there is already a node with this name
if(!parent.hasChild(data))
{
Group group = new Group();
group.setName(data);
parent.addChild(data, group);
}
}
else
{
// pass the tail of this path down to the next level in the hierarchy
addData(parent.getChild(data), path.subList(1, path.size()));
}
}
public Group getData(String[] path)
{
return (Group) getData(this, Arrays.asList(path));
}
public Group getData(List<String> path)
{
return (Group) getData(this, path);
}
private TreeItem getData(TreeItem parent, List<String> path)
{
if(parent == null || path.size() == 0)
{
throw new IllegalArgumentException("Invalid path specified in getData, remainder: "
+ Arrays.toString(path.toArray()));
}
String data = path.get(0);
if(path.size() == 1)
{
return parent.getChild(data);
}
else
{
// pass the tail of this path down to the next level in the hierarchy
return getData(parent.getChild(data), path.subList(1, path.size()));
}
}
}
public static class Group extends TreeItem {
private Map<String, Object> properties;
public Object getValue(Object key) {
return properties.get(key);
}
public Object putValue(String key, Object value) {
return properties.put(key, value);
}
public Group () {
super();
properties = new HashMap<String, Object>();
}
}
}
我认为这符合你到目前为止提到的大多数要求,虽然我把MPG值的平均值作为读者的练习(我只有这么多时间......)。这个解决方案非常通用 - 您可能需要更具体的子类来更好地描述您的数据模型(如制造商,类型,模型),因为您可以将更多有用的方法挂起来(比如计算子项中的字段平均值)对象)
,您不必将这些属性作为Object
的集合来处理,但是您可以从列表中获得更复杂的代码来初始化您的数据结构。注意 - 这不是生产就绪代码,我刚刚提供了它作为如何用Java建模数据的示例。
如果您不仅是Java新手,而是Object Orientated Programming,那么您应该阅读这个主题。我在这里写的代码并不完美,我已经可以看到它可以改进的方法了。学习编写高质量的面向对象的代码需要时间和练习。阅读Design Patterns和Code Smells。