将数组转换为分层 JSONArray
Convert an array to hierarchical JSONArray
假设我有一个代表包结构的字符串数组。
它看起来像这样:
Array {
"com.project.server",
"com.project.client",
"com.project.client.util",
...
}
未定义一个包可以包含多少层。
现在我想将其转换为分层的 JSON-Object。
这应该是这样的:
{
"name": "com",
"children": [
{
"name": "project",
"children": [
{
"name": "server"
},
{
"name": "client",
"children": [
{
"name": "util"
}
]
}
]
}
]
}
希望你能明白我的意思
说实话,我被无可救药地质疑了...
你能帮帮我吗?
谢谢,抱歉可能英语不好。
给你!
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
public class ParseTree {
public PackageInfo getRoot(List<String> packages) throws JsonProcessingException {
Map<String, PackageInfo> map = new HashMap<>();
String root = null;
for (String packageName : packages) {
String[] split = packageName.split("\.");
for (int i = 0; i < split.length; i++) {
String singlePackage = split[i];
if (root == null) {
root = singlePackage;
}
map.computeIfAbsent(singlePackage, PackageInfo::new);
if (i - 1 >= 0) {
PackageInfo currentPackage = map.get(singlePackage);
map.get(split[i - 1]).getChildren().add(currentPackage);
}
}
}
return map.get(root);
}
public static void main(String[] args) throws JsonProcessingException {
List<String> packages = Arrays.asList("com.project.server",
"com.project.client",
"com.project.client.util", "com.project.client.util.some");
ParseTree parseTree = new ParseTree();
PackageInfo root = parseTree.getRoot(packages);
ObjectMapper mapper = new ObjectMapper();
System.out.println(mapper.writeValueAsString(root));
}
}
class PackageInfo {
private String name;
private Set<PackageInfo> children;
public PackageInfo(String name) {
this.name = name;
children = new HashSet<>();
}
public Set<PackageInfo> getChildren() {
return children;
}
public String getName() {
return name;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
PackageInfo that = (PackageInfo) o;
return Objects.equals(name, that.name);
}
@Override
public int hashCode() {
return Objects.hash(name);
}
@Override
public String toString() {
return "PackageInfo{" +
"name='" + name + '\'' +
", children=" + children +
'}';
}
}
它将为您提供
的输出
{
"name":"com",
"children":[
{
"name":"project",
"children":[
{
"name":"server",
"children":[
]
},
{
"name":"client",
"children":[
{
"name":"util",
"children":[
{
"name":"some",
"children":[
]
}
]
}
]
}
]
}
]
}
听起来你需要 Java 中的树结构。已经讨论了多种解决方案 here。
然后您可以以标准方式转换 input/output JSON。
对于包的具体问题,请考虑使用树状实现。您可以使树只包含唯一节点。这将使您能够将数据转换为正确的格式。
下面是一些关于如何创建你想要的树的伪代码:
class Tree
Tree[] children
String data;
现在要向这棵树添加内容,您只需像链表一样遍历它,这意味着您添加了按编号访问子项的方法。此外,当您添加节点时,通过将它们与您正在添加的级别上已经存在的节点进行比较,确保它们是唯一的。由于您更关注从 Tree 到 Json 的实际转换。
一种可能的算法是递归遍历树并从中创建一个 String
,如下所示:
public String getJsonFormat(Tree root){
for(Tree child : root.getChildren())
{
return "{\n\"name\":\"" + child.data + "\", \n\"children\":[\n" + getJsonFormat(child) + "\n}"
}
现在您可以使用 Json。要将内容添加到树中,这里有一个关于如何执行此操作的算法。
addStuffToTree(String packagePath)
{
array = packagePath.split("\.");
//We now know that the elements in the array, correspond to the level of the tree they are supposed to be in, therefore:
Tree temp = root; //new Tree which is equal to your root
if(temp.data != array[0])
for( i=1; i < array.length; i++){
for(Tree tree : temp.getChildren())
if(tree.data == array[i])
{temp=tree;
i++;
// We will traverse the tree like this, avoiding duplicates
}
temp.add(array[i])
temp = newest child
//This adds a node if it hasn't been there yet if there are more iterations, it will continue running under that node, if not it will exit the loop
}
抱歉,这不是很漂亮,是在我的 phone 上制作的。
与其他解决方案没有太大区别,但既然我这样做了,就给你
@Data
public class Node {
String name;
List<Node> children;
public Node(String name) {
this.name = name;
children = new ArrayList<>();
}
}
public static void main(String[] args) {
List<String> a = Arrays.asList(
"com.project.server",
"com.project.client",
"com.project.client.util"
);
List<Node> root = new ArrayList<>();
for (String s: a) {
List<String> packs = Arrays.asList(s.split("\."));
List<Node> current = root;
for (String pack : packs) {
Optional<Node> newCur = current.stream().filter(node -> node.name.equals(pack)).findFirst();
if (newCur.isPresent()) {
current = newCur.get().children;
} else {
Node newNode = new Node(pack);
current.add(newNode);
current = newNode.children;
}
}
}
System.out.println(root);
}
json 转换应该是非常标准的
使用 lomboks 生成的 toString 输出:
[Node(name=com, children=[Node(name=project, children=[Node(name=server, children=[]), Node(name=client, children=[Node(name=util, children=[])])])])]
假设我有一个代表包结构的字符串数组。 它看起来像这样:
Array {
"com.project.server",
"com.project.client",
"com.project.client.util",
...
}
未定义一个包可以包含多少层。
现在我想将其转换为分层的 JSON-Object。 这应该是这样的:
{
"name": "com",
"children": [
{
"name": "project",
"children": [
{
"name": "server"
},
{
"name": "client",
"children": [
{
"name": "util"
}
]
}
]
}
]
}
希望你能明白我的意思
说实话,我被无可救药地质疑了...
你能帮帮我吗? 谢谢,抱歉可能英语不好。
给你!
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
public class ParseTree {
public PackageInfo getRoot(List<String> packages) throws JsonProcessingException {
Map<String, PackageInfo> map = new HashMap<>();
String root = null;
for (String packageName : packages) {
String[] split = packageName.split("\.");
for (int i = 0; i < split.length; i++) {
String singlePackage = split[i];
if (root == null) {
root = singlePackage;
}
map.computeIfAbsent(singlePackage, PackageInfo::new);
if (i - 1 >= 0) {
PackageInfo currentPackage = map.get(singlePackage);
map.get(split[i - 1]).getChildren().add(currentPackage);
}
}
}
return map.get(root);
}
public static void main(String[] args) throws JsonProcessingException {
List<String> packages = Arrays.asList("com.project.server",
"com.project.client",
"com.project.client.util", "com.project.client.util.some");
ParseTree parseTree = new ParseTree();
PackageInfo root = parseTree.getRoot(packages);
ObjectMapper mapper = new ObjectMapper();
System.out.println(mapper.writeValueAsString(root));
}
}
class PackageInfo {
private String name;
private Set<PackageInfo> children;
public PackageInfo(String name) {
this.name = name;
children = new HashSet<>();
}
public Set<PackageInfo> getChildren() {
return children;
}
public String getName() {
return name;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
PackageInfo that = (PackageInfo) o;
return Objects.equals(name, that.name);
}
@Override
public int hashCode() {
return Objects.hash(name);
}
@Override
public String toString() {
return "PackageInfo{" +
"name='" + name + '\'' +
", children=" + children +
'}';
}
}
它将为您提供
的输出{
"name":"com",
"children":[
{
"name":"project",
"children":[
{
"name":"server",
"children":[
]
},
{
"name":"client",
"children":[
{
"name":"util",
"children":[
{
"name":"some",
"children":[
]
}
]
}
]
}
]
}
]
}
听起来你需要 Java 中的树结构。已经讨论了多种解决方案 here。
然后您可以以标准方式转换 input/output JSON。
对于包的具体问题,请考虑使用树状实现。您可以使树只包含唯一节点。这将使您能够将数据转换为正确的格式。 下面是一些关于如何创建你想要的树的伪代码:
class Tree
Tree[] children
String data;
现在要向这棵树添加内容,您只需像链表一样遍历它,这意味着您添加了按编号访问子项的方法。此外,当您添加节点时,通过将它们与您正在添加的级别上已经存在的节点进行比较,确保它们是唯一的。由于您更关注从 Tree 到 Json 的实际转换。
一种可能的算法是递归遍历树并从中创建一个 String
,如下所示:
public String getJsonFormat(Tree root){
for(Tree child : root.getChildren())
{
return "{\n\"name\":\"" + child.data + "\", \n\"children\":[\n" + getJsonFormat(child) + "\n}"
}
现在您可以使用 Json。要将内容添加到树中,这里有一个关于如何执行此操作的算法。
addStuffToTree(String packagePath)
{
array = packagePath.split("\.");
//We now know that the elements in the array, correspond to the level of the tree they are supposed to be in, therefore:
Tree temp = root; //new Tree which is equal to your root
if(temp.data != array[0])
for( i=1; i < array.length; i++){
for(Tree tree : temp.getChildren())
if(tree.data == array[i])
{temp=tree;
i++;
// We will traverse the tree like this, avoiding duplicates
}
temp.add(array[i])
temp = newest child
//This adds a node if it hasn't been there yet if there are more iterations, it will continue running under that node, if not it will exit the loop
}
抱歉,这不是很漂亮,是在我的 phone 上制作的。
与其他解决方案没有太大区别,但既然我这样做了,就给你
@Data
public class Node {
String name;
List<Node> children;
public Node(String name) {
this.name = name;
children = new ArrayList<>();
}
}
public static void main(String[] args) {
List<String> a = Arrays.asList(
"com.project.server",
"com.project.client",
"com.project.client.util"
);
List<Node> root = new ArrayList<>();
for (String s: a) {
List<String> packs = Arrays.asList(s.split("\."));
List<Node> current = root;
for (String pack : packs) {
Optional<Node> newCur = current.stream().filter(node -> node.name.equals(pack)).findFirst();
if (newCur.isPresent()) {
current = newCur.get().children;
} else {
Node newNode = new Node(pack);
current.add(newNode);
current = newNode.children;
}
}
}
System.out.println(root);
}
json 转换应该是非常标准的
使用 lomboks 生成的 toString 输出:
[Node(name=com, children=[Node(name=project, children=[Node(name=server, children=[]), Node(name=client, children=[Node(name=util, children=[])])])])]