本来只是在想怎么把有三级的数据存储的 想想好像可以搞个通用的 。本来是想 是把每级下的子集都放到List里的 当分析下一个的时候就看List里有没有 没有就创建 但这个要疯狂遍历找路径 于是就想到 如果把加入到children里的对象 都有一个Map能直接找到 那就方便多了 于是就有了下面
list 和 Map 的组合 同一个节点下 有list和Map Map里每一个简直对对应的value都在list里 为了让那个节点有可以有更多的信息 于是就用date封装list 就有了date 和 Map 下面是我的实现
item是指一个自定义的对象 里面有chilren 也就是下级
ItemWithMap 是一个封装的对象 里面的主要是一个该节点下面的date 以及属于这个一级开始的
Map<String,ItemWIthMap> ,这个date的对象是个自定义的对象item ,但是里面需要一个List 里有录该Map<String,ItemWIthMap>里的每一个ItemWithMap里的item 这样一级记录一级 相当于用Map映射到List的每一个数据 ,所以 每次我们要往ItemWithMap的Map里put的时候, 同时把put里的item 向ItemWithMap 里date (item)里的list加。
这样子 我们最终可以通过一开始的Map 通过把value遍历 便可以拿到同一级下的ItemWithMap 在把里面的item拿出来 这样得到的结果就是一个已经把所有下级都装好的所有一级item了
下面我来应用一下这个想法
首先是准备好item在没有装children时候的item的url
然后是item
import java.util.ArrayList;
import java.util.List;
public class Item {
private String url;
private List<Item> children;
@Override
public String toString() {
return "Item{" +
"url='" + url + '\'' +
", children=" + children +
'}';
}
//new的时候就初始化了 免得后面又要判断 现在new完可以直接塞
public Item() {
this.children = new ArrayList<>();
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public List<Item> getChildren() {
return children;
}
public void setChildren(List<Item> children) {
this.children = children;
}
}
然后是ItemWithMap
package com.example.demo.pojo;
import java.util.Map;
public class ItemWithMap<T> {
private T date;
private Map<String,ItemWithMap<T>> map;
@Override
public String toString() {
return "ItemWithMap{" +
"date=" + date +
", map=" + map +
'}';
}
public T getDate() {
return date;
}
public void setDate(T date) {
this.date = date;
}
public Map<String, ItemWithMap<T>> getMap() {
return map;
}
public void setMap(Map<String, ItemWithMap<T>> map) {
this.map = map;
}
}
测试代码如下 为了方便 利用SpringMVC框架 把结果变成json 返回前端 再用Notepad++插件 变成好看点的结果
@GetMapping("T")
public Object T(){
//利用mybatis把从数据库查询到的数据塞入Item里
List<Item> items = mapper.listItem();
Map<String,ItemWithMap<Item>> map=new HashMap<>(); //作为最终形成的map
Map<String,ItemWithMap<Item>> curmap=map;//定位到map
Map<String,ItemWithMap<Item>> premap=null;//上一层的map
//开始对每一个数据进行解析后 放入对应的children里和map里
for (Item item : items) {
String url = item.getUrl();
String[] split = url.split("\\\\");
int level = split.length;
//确定好有多少级的树有多少级就要分析多少次
for (int i = 0; i <level ; i++) {
//判断这个级 有没有相关映射 如果没有就创建
if (!curmap.containsKey(split[i])) {
ItemWithMap<Item> newIWM = new ItemWithMap<>();
Item newitem = new Item();
newitem.setUrl(split[i]);
newIWM.setDate(newitem);//新建时候初始化完但为空
newIWM.setMap(new HashMap<>());
//创建好当前级 ItemWithMap 也就是 Item和这个级下的Map
curmap.put(split[i], newIWM);
//下面的判断用于 如果当前的 ItemWithMap为上一个Map中 那么就
//需要把这个 ItemWithMap中的item 加到上一个item的children里
//也就是Map里的所有的键值对 都在item的children 形成映射
if (i > 0) {
premap.get(split[i - 1]).getDate().getChildren().add(newitem);
}
}
premap = curmap;//记录当前级
curmap = curmap.get(split[i]).getMap();//进入到下一个级
}
//当遍历完这个item的所有级时候 刷新当前节点 与上一个节点 也就是让
//curmap和premap回到最初状态
curmap=map;
premap=null;
}
//当所有的item都被分析好了 map里就是所有的一级的ItemWithMap<Item>
//其中的date 也就是item 也是一级的
//创建一个list来装
List<Item> itemList =new ArrayList<>();
//遍历所有ItemWithMap<Item> 拿出里面的item 放进list里
Collection<ItemWithMap<Item>> values = map.values();
for (ItemWithMap<Item> value : values) {
itemList.add(value.getDate());
}
return itemList;
}
最终的结果为
[
{
"url": "a1",
"children": [
{
"url": "b1",
"children": [
{
"url": "c1",
"children": []
},
{
"url": "c2",
"children": []
},
{
"url": "c3",
"children": []
}
]
},
{
"url": "b2",
"children": [
{
"url": "c1",
"children": []
}
]
}
]
},
{
"url": "a2",
"children": [
{
"url": "b1",
"children": [
{
"url": "c1",
"children": []
},
{
"url": "c2",
"children": []
}
]
},
{
"url": "b2",
"children": []
},
{
"url": "b3",
"children": []
}
]
}
]