樹格式數據的構造(Java拼接)

1.導入json相關的jar包

2.JsonTreeHelper.java

3.調用getTreeJsonStr方法:

      nodesNameBySeq:待分組的節點名稱.將樹節點對應的實體類的成員名稱放到此數組裏面,順序是{"根節點","子節點1","子節點2"...}
      data:數據列表,List<實體類> data ; 

說明:樹默認是節點關閉狀態,json中只有id,text,state字段

編寫原理:

1).首先用groupByNodeName將數據分組

        用Java中的Field進行字段比較,來獲得相對應的成員字段,以及成員變量的名稱,這裏要用getDeclaredFields方法來獲得,否則,private聲明的成員是無法得到Field的

        將得到的fieldIndex全部放到數組中保存,便於以後的使用,field[fieldIndex]可以得到相應的字段

2).構造一個tree的json形式的類:裏面有幾個重要的成員:{id,text,state}這種形式用JsonObject.fromObject(jsonObj}能直接轉換爲tree所需要的json,並且,這個類中要有一

        個children字段,保存子節點的數據

3).recursiveTree方法

       # 此方法內要遞歸遍歷樹,返回一個list,list中是一個JsonTreeObj自定義的一個類,其中的children還可以保存一個JsonTreeObj,這樣就可以實現嵌套

       #在遞歸之前,首先要有一個成員變量(全局變量)來記錄要分組的節點索引

      先進行一次分組,得到的map就是JsonTreeObj,通過構造方法可以實現轉換,這樣,轉換過來的JsonTreeObj纔是我們的Tree-json,但這只是一次調用

      是否再次分組,要用事先準備好的    fieldIndex長度或者nodesNameBySeq進行判斷,如果要繼續分組,那麼需要移除map中每條數據中的list並重新分組成map.

      即:用新分組的List替換以前未分組的List

      返回之後,返回分組好的JsonTreeObj數據,此時的list差不多和需要的json相仿但是,還要做下字符串的調整

4).replaceText

      用此方法來替換最深層節點的文本,否則字段中無text,會出現undefine

4.示例

1)要構造的樹


2)要構造的json

[
    {
        "children": [
            {
                "children": [
                    {
                        "children": [
                            {
                                "address": "bj",
                                "text": "id1",
                                "name": "wang'ao1",
                                "occupation": "student"
                            }
                        ],
                        "id": "0.5715806450144063",
                        "state": "closed",
                        "text": "student"
                    }
                ],
                "id": "0.4010186645348438",
                "state": "closed",
                "text": "bj"
            },
            {
                "children": [
                    {
                        "children": [
                            {
                                "address": "bj11",
                                "text": "id12",
                                "name": "wang'ao1",
                                "occupation": "student"
                            }
                        ],
                        "id": "0.188373241944635",
                        "state": "closed",
                        "text": "student"
                    },
                    {
                        "children": [
                            {
                                "address": "bj11",
                                "text": "id11",
                                "name": "wang'ao1",
                                "occupation": "teacher"
                            }
                        ],
                        "id": "0.9566645560486874",
                        "state": "closed",
                        "text": "teacher"
                    }
                ],
                "id": "0.6062106288555755",
                "state": "closed",
                "text": "bj11"
            }
        ],
        "id": "0.6856242232995936",
        "state": "closed",
        "text": "wang'ao1"
    },
    {
        "children": [
            {
                "children": [
                    {
                        "children": [
                            {
                                "address": "bj",
                                "text": "id1",
                                "name": "wang'ao",
                                "occupation": "student"
                            }
                        ],
                        "id": "0.5044856120294572",
                        "state": "closed",
                        "text": "student"
                    }
                ],
                "id": "0.2021652373692504",
                "state": "closed",
                "text": "bj"
            },
            {
                "children": [
                    {
                        "children": [
                            {
                                "address": "bj11",
                                "text": "id12",
                                "name": "wang'ao",
                                "occupation": "student"
                            }
                        ],
                        "id": "0.7096934456298796",
                        "state": "closed",
                        "text": "student"
                    },
                    {
                        "children": [
                            {
                                "address": "bj11",
                                "text": "id11",
                                "name": "wang'ao",
                                "occupation": "teacher"
                            }
                        ],
                        "id": "0.8679325026402117",
                        "state": "closed",
                        "text": "teacher"
                    }
                ],
                "id": "0.6940289758188156",
                "state": "closed",
                "text": "bj11"
            }
        ],
        "id": "0.08304442224761122",
        "state": "closed",
        "text": "wang'ao"
    }
]


3)實體類

/**
 * @author wang'ao
 *
 */
public class TestEntity {

	private String name ;
	private String ids ;
	private String address ;
	private String occupation ;
	
	public String getOccupation() {
		return occupation;
	}
	public void setOccupation(String occupation) {
		this.occupation = occupation;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getIds() {
		return ids;
	}
	public void setId(String ids) {
		this.ids = ids;
	}
	public String getAddress() {
		return address;
	}
	public void setAddress(String address) {
		this.address = address;
	}
	
	public TestEntity(String name, String ids, String address, String occupation) {
		super();
		this.name = name;
		this.ids = ids;
		this.address = address;
		this.occupation = occupation;
	}
	@Override
	public String toString() {
		return "TestEntity [name=" + name + ", id=" + ids + ", address="
				+ address + "]";
	}
	
	
}


4)測試

/**
 * @author wang'ao
 * 
 */
public class Test {
	public static void main(String[] args) throws SecurityException,
			NoSuchMethodException, IllegalArgumentException,
			IllegalAccessException, InvocationTargetException {
		TestEntity te1 = new TestEntity("wang'ao","id1","bj","student") ;
		TestEntity te2 = new TestEntity("wang'ao","id11","bj11","teacher") ;
		TestEntity te3 = new TestEntity("wang'ao","id12","bj11","student") ;
		
		TestEntity te4 = new TestEntity("wang'ao1","id1","bj","student") ;
		TestEntity te5 = new TestEntity("wang'ao1","id11","bj11","teacher") ;
		TestEntity te6 = new TestEntity("wang'ao1","id12","bj11","student") ;
		List<Object> list = new ArrayList<Object>() ;
		list.add(te1) ;
		list.add(te2) ;
		list.add(te3) ;
		list.add(te4) ;
		list.add(te5) ;
		list.add(te6) ;
		System.out.println("jsonTree:" + 
				JsonTreeHelper.getTreeJsonStr(new String[]{"name","address","occupation","ids"}, list)
				);
	}
}

JsonTreeHelper.java


/**   
 *
 * @version V1.0   
 */


import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import net.sf.json.JSONArray;

/**
 * 用途:json樹的數據生成類 
 * 描述:將數據列表轉換成相應的tree所必需的JSON格式 
 * 說明:N級節點樹,默認樹節點是關閉的
 * 
 * @author wang'ao
 * 
 */
public class JsonTreeHelper {
	/**
	 * 用於頁面傳遞JSON數據的類,id:xx text:xx children:xx
	 * 將從數據庫查詢到的數據,用這個類進行打包,而可以將這個類直接轉換成 指定的格式的JSON字符串
	 * 
	 * tip:如有需要,直接繼承,並添加一個自定義字段
	 * 
	 * @author wang'ao
	 * 
	 */
	public static class JsonTreeObj {
		/** 必需的id **/
		private String id;
		/** 顯示的節點文本 **/
		private String text;
		/** 是否是關閉狀態 **/
		private String state;
		/** 子 **/
		private List<Object> children;

		/**
		 * 
		 * @param text
		 *            節點的文本名字
		 * @param children
		 *            內部節點集合
		 */
		public JsonTreeObj(String rootNode, List<Object> children) {
			/** 保證id不重複 **/
			this.id = Math.random() + "";
			this.state = "closed";
			this.text = rootNode;
			this.children = children;
		}

		public String getId() {
			return id;
		}

		public void setId(String id) {
			this.id = id;
		}

		public String getText() {
			return text;
		}

		public void setText(String text) {
			this.text = text;
		}

		public String getState() {
			return state;
		}

		public void setState(String state) {
			this.state = state;
		}

		public List<Object> getChildren() {
			return children;
		}

		public void setChildren(List<Object> children) {
			this.children = children;
		}

	}

	/**
	 * 用途:轉換tree形式數據 用例: 實體類:class People{private String name ;private String
	 * hometown ;private String occupation ; set...;get...}
	 * 調用方法:getTreeJsonStr(new String[]{"hometown","occupation"},data);
	 * 說明:表示以hometown爲根節點,occupation字段爲子節點所構成的樹
	 * 
	 * @param nodesNameBySeq
	 *            樹節點名字數組 {"根節點","子節點1","子節點2",...} ,此處的名字應是對應的實體類的成員名.
	 *            如:有一個成員{private String type ;} 根節點是"type"
	 * @param data
	 *            數據
	 * @return tree形式的JSON數據
	 * @throws IllegalArgumentException
	 * @throws IllegalAccessException
	 */
	public static String getTreeJsonStr(String[] nodesNameBySeq,List<Object> data) throws IllegalArgumentException,
			IllegalAccessException {

		int[] fieldIndex = new int[nodesNameBySeq.length];
		// 優化標記
		int end = 0;
		Field[] fields = data.get(0).getClass().getDeclaredFields();
		for (int i = 0; i < nodesNameBySeq.length; i++) {
			for (int j = 0; j < fields.length; j++) {

				if (nodesNameBySeq[i].equals(fields[j].getName())) {
					fieldIndex[i] = j;
					end++;
					if (end == nodesNameBySeq.length)
						break;
				}
			}

		}
		// 替換成text字段
		return replaceText(JSONArray
				.fromObject(recursiveTree(data, fieldIndex)).toString(),
				nodesNameBySeq[nodesNameBySeq.length - 1], "text");

	}

	/**
	 * 將數據根據根節點進行分組
	 * 
	 * @param fieldIndex
	 *            根節點成員字段所對應折field索引
	 * @param list
	 *            數據列表
	 * @return 分組好的map數據
	 * @throws IllegalArgumentException
	 * @throws IllegalAccessException
	 */
	private static Map<String, List<Object>> groupByNodeName(
			Integer fieldIndex, List<Object> list)
			throws IllegalArgumentException, IllegalAccessException {
		// 準備集合
		Map<String, List<Object>> readyMap = new HashMap<String, List<Object>>();
		for (int i = 0; i < list.size(); i++) {
			java.lang.reflect.Field[] field = (java.lang.reflect.Field[]) list
					.get(i).getClass().getDeclaredFields();
			field[fieldIndex].setAccessible(true);
			List<Object> find = readyMap.get(field[fieldIndex].get(list.get(i))
					.toString());
			if (readyMap.isEmpty() || find == null) {
				List<Object> similar = new ArrayList<Object>();
				similar.add(list.get(i));
				readyMap.put(field[fieldIndex].get(list.get(i)).toString(),
						similar);
			} else {
				find.add(list.get(i));
				readyMap.put(field[fieldIndex].get(list.get(i)).toString(),
						find);
			}

		}

		return readyMap;
	}

	private static int fIndex = 0;

	/**
	 * 遍歷所有節點(遞歸調用)
	 * 
	 * @param data
	 * @param fieldIndexF
	 * @return
	 * @throws IllegalArgumentException
	 * @throws IllegalAccessException
	 */
	private static List<JsonTreeObj> recursiveTree(List<Object> data,
			int[] fieldIndexF) throws IllegalArgumentException,
			IllegalAccessException {

		// 先進行一次分組
		Map<String, List<Object>> firstGroupedData = groupByNodeName(
				fieldIndexF[fIndex], data);
		List<JsonTreeObj> jsonTrees = new ArrayList<JsonTreeObj>();
		// 第一次分組的數據
		Iterator<Map.Entry<String, List<Object>>> it = firstGroupedData
				.entrySet().iterator();
		int i = 0;
		List<Object> list;
		// 遍歷map
		while (it.hasNext()) {

			Map.Entry<String, List<Object>> entry = it.next();
			jsonTrees.add(new JsonTreeObj(entry.getKey(), entry.getValue()));
			if (fieldIndexF.length > 1 && fIndex < fieldIndexF.length - 2) {
				fIndex++;
				// **.clear()方法要清除指針,所以要用new方法實例化
				list = new ArrayList<Object>(entry.getValue());
				jsonTrees.get(i).getChildren().clear();
				jsonTrees.get(i).getChildren()
						.addAll((recursiveTree(list, fieldIndexF)));

			}
			i++;
		}
		fIndex--;

		return jsonTrees;
	}

	/**
	 * 將JSON串中的字符替換,如:"post" -> "text" ,這樣可以正常顯示文本,否則 undefine
	 * 
	 * @param src
	 *            源JSON
	 * @param replace
	 *            要替換的字段
	 * @param changedTxt
	 *            替換之後的字段
	 * @return 替換完成之後的字段
	 */
	private static String replaceText(String src, String replace,
			String changedTxt) {
		return src.replaceAll("\"" + replace + "\"", "\"" + changedTxt + "\"");
	}

}






第一次寫博客,請多諒解吐舌頭

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章