整體思路是將之前的對象,用List<Map<String, Object>>的方式包起來。
Map作為樹中的“節(jié)點”,其中有兩個key,data--數(shù)據(jù)本身,children--又一個List<Map<String, Object>>存放子“節(jié)點”。
總的來說分兩步。
第一步,將所有parent值為null的節(jié)點先放入最后返回的結(jié)果集中。
因為這些值沒有父節(jié)點,必定在樹型結(jié)果集的第一層,可以率先放入。

由于是制作成工具,所以取id和parentId的操作使用了反射。
DATA_FIELD其實就是字符串常量,也就是上方提到的map中的"data"字段。
map.put((String) getSelfIdMethod.invoke(node), true)這句話后面會做解釋。
第二步,遍歷所有列表數(shù)據(jù),并依次添加進現(xiàn)有的樹型結(jié)果集中。

同理,map.put((String)getSelfIdMethod.invoke(node), true)同理這句話后面作解釋。

在理解了這兩個核心步驟的前提下,現(xiàn)在來解釋關(guān)于上面方法中的map的問題。
上面的方法存在一個問題,就是列表結(jié)果集(list)本身數(shù)據(jù)的順序是數(shù)據(jù)庫查出來的,也就是不確定的。
如果按照順序方式只遍歷一遍來放入樹型結(jié)果集(resultList)中,那么有可能出現(xiàn)這樣一種情況。
如:節(jié)點B的父節(jié)點是A,同樣A也有父節(jié)點(有父節(jié)點的意思是不保證A在第一步中會被率先放入)。
但是在list中,B是在比A更靠前的位置,所以可能出現(xiàn),企圖將B加入樹型結(jié)果集的時候,A還不存在結(jié)果集里。
這次遍歷中,B便無法放入樹型結(jié)果集中,那么如果只遍歷一次,B就被遺漏了。
目前第一版解決方案就是圖中的方法,將已經(jīng)放入resultList的節(jié)點存入map。
并一直循環(huán)直到確保所有l(wèi)ist數(shù)據(jù)都放入resultList才停止。

現(xiàn)在我們能確保所有結(jié)果都能放入resultList了。但是如圖,我們面臨了新的問題。
數(shù)據(jù)庫的數(shù)據(jù)如果讓數(shù)據(jù)成環(huán),比如兩列數(shù)據(jù)互為parent這種情況。
while (map.size() < list.size())這句代碼會讓這個方法進入死循環(huán)。
下一節(jié)我們繼續(xù)解決這個問題。