Java實(shí)現(xiàn)樹(shù)形List與扁平List互轉(zhuǎn)的示例代碼
背景:在平時(shí)的開(kāi)發(fā)中,我們時(shí)常會(huì)遇到下列場(chǎng)景
- 公司的組織架構(gòu)的數(shù)據(jù)存儲(chǔ)與展示
- 文件夾層級(jí)的數(shù)據(jù)存儲(chǔ)與展示
- 評(píng)論系統(tǒng)中,父評(píng)論與諸多子評(píng)論的數(shù)據(jù)存儲(chǔ)與展示
- ......
對(duì)于這種有層級(jí)的結(jié)構(gòu)化數(shù)據(jù),就像是一棵樹(shù)一樣。在關(guān)系型數(shù)據(jù)庫(kù)中,通常將一個(gè)個(gè)的節(jié)點(diǎn)信息存儲(chǔ)到表中,通過(guò)一個(gè)字段(例如,pid),指向其父節(jié)點(diǎn)。而在數(shù)據(jù)展示的時(shí)候,我們又希望它是呈現(xiàn)層級(jí)的,例如:
id name pid 1 總公司 -1 2 上海分公司 1 3 浙江分公司 1 4 閔行區(qū)分公司 2 5 嘉興分公司 3 { "id": 1, "name": "總公司", "pid": -1, "branch": [ { "id": 2, "name": "上海分公司", "pid": 1, "branch": [ { "id": 4, "name": "閔行區(qū)分公司", "pid": 2, "branch": [] } ] }, { "id": 3, "name": "浙江分公司", "pid": 1, "branch": [ { "id": 5, "name": "嘉興分公司", "pid": 3, "branch": [] } ] } ] }
所以,本文的主要內(nèi)容就是提供幾種方案,實(shí)現(xiàn)這兩類數(shù)據(jù)的轉(zhuǎn)換方式。
存儲(chǔ)樹(shù)的表結(jié)構(gòu)
如何在一張數(shù)據(jù)庫(kù)表中表示一顆樹(shù)結(jié)構(gòu)中的所有節(jié)點(diǎn)信息,這里有一個(gè)示例:
DROP TABLE IF EXISTS zj_city; CREATE TABLE zj_city ( id BIGINT NOT NULL AUTO_INCREMENT, name VARCHAR(50) COMMENT '節(jié)點(diǎn)名稱', pid int NOT NULL COMMENT '父節(jié)點(diǎn)', create_time DATETIME DEFAULT now() COMMENT '創(chuàng)建時(shí)間: 年-月-日 時(shí):分:秒', update_time DATETIME DEFAULT now() ON UPDATE now() COMMENT '更新時(shí)間', is_deleted BIT DEFAULT 0 COMMENT '是否刪除:0-false-未刪除;1-true-已刪除', PRIMARY KEY (id) )COMMENT '浙江城市'; INSERT INTO zj_city(name, pid) VALUES ('浙江省',0), ('金華市',1), ('嘉興市',1), ('杭州市',1), ('寧波市',1); INSERT INTO zj_city(name, pid) VALUES ('下城區(qū)',4), ('錢塘區(qū)',4), ('西湖區(qū)',4), ('上城區(qū)',4); INSERT INTO zj_city(name, pid) VALUES ('南湖區(qū)',3), ('秀洲區(qū)',3), ('桐鄉(xiāng)市',3), ('平湖市',3), ('海寧市',3); INSERT INTO zj_city(name, pid) VALUES ('梧桐街道',12), ('鳳鳴街道',12), ('龍翔街道',12), ('崇福鎮(zhèn)',12), ('烏鎮(zhèn)鎮(zhèn)',12), ('高橋鎮(zhèn)',12), ('河山鎮(zhèn)',12), ('濮院鎮(zhèn)',12); SELECT * from zj_city;
扁平List轉(zhuǎn)樹(shù)形List
應(yīng)用場(chǎng)景
- 公司組織結(jié)構(gòu)
- 省市級(jí)
- 評(píng)論系統(tǒng)中,父評(píng)論與諸多子評(píng)論
- 其他層級(jí)展示的數(shù)據(jù)
雙層for
主要思想:外層循環(huán)-找父節(jié)點(diǎn);內(nèi)層循環(huán)-找子節(jié)點(diǎn);因?yàn)槊總€(gè)元素都會(huì)找一遍,所有最終得到完整的樹(shù)
import com.alibaba.fastjson.JSON; import com.ks.boot.entity.CityEntity; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import java.util.ArrayList; import java.util.List; public class TreeListDemo { List<CityEntity> cityEntities; /** * id name pid * 1 浙江 0 * 2 杭州 1 * 3 嘉興 1 * 4 南湖 3 * 5 桐鄉(xiāng) 3 * 6 余杭 2 * 7 西湖 2 * 8 云南 0 * 9 昆明 8 * 10 昭通 8 */ @BeforeEach public void init() { cityEntities = JSON.parseArray("[{\"id\":1,\"name\":\"浙江\",\"pid\":0},\n" + "{\"id\":2,\"name\":\"杭州\",\"pid\":1},\n" + "{\"id\":3,\"name\":\"嘉興\",\"pid\":1},\n" + "{\"id\":4,\"name\":\"南湖\",\"pid\":3},\n" + "{\"id\":5,\"name\":\"桐鄉(xiāng)\",\"pid\":3},\n" + "{\"id\":6,\"name\":\"余杭\",\"pid\":2},\n" + "{\"id\":7,\"name\":\"西湖\",\"pid\":2},\n" + "{\"id\":8,\"name\":\"云南\",\"pid\":0},\n" + "{\"id\":9,\"name\":\"昆明\",\"pid\":8},\n" + "{\"id\":10,\"name\":\"昭通\",\"pid\":8}]", CityEntity.class); } @Test public void testList2Tree() { List<CityEntity> resultTree = list2Tree(this.cityEntities); System.out.println(JSON.toJSONString(resultTree)); } /** * 雙層for,List轉(zhuǎn)Tree * 主要思想:外層循環(huán)-找父節(jié)點(diǎn);內(nèi)層循環(huán)-找子節(jié)點(diǎn);因?yàn)槊總€(gè)元素都會(huì)找一遍,所有最終得到完整的樹(shù) * 時(shí)間復(fù)雜度:N^2;空間復(fù)雜度:N */ public List<CityEntity> list2Tree(List<CityEntity> cityEntities) { List<CityEntity> resultCities = new ArrayList<>(); for (CityEntity city : cityEntities) { if(0 == city.getPid()) { //根節(jié)點(diǎn)、頂級(jí)節(jié)點(diǎn),直接放入最終返回結(jié)果的List resultCities.add(city); } for (CityEntity curCity : cityEntities) { //根據(jù)當(dāng)前city找它的子節(jié)點(diǎn) if(city.getId().equals(curCity.getPid())) { if(city.getSubCityList() == null) { //還沒(méi)有任何子節(jié)點(diǎn),new一個(gè)空的放進(jìn)去 city.setSubCityList(new ArrayList<>()); } city.getSubCityList().add(curCity); } } } return resultCities; } } public class CityEntity { private Long id; private String name; private Long pid; private List<CityEntity> subCityList; getter/setter }
遞歸
主要思想:獲取所有根節(jié)點(diǎn)、頂級(jí)節(jié)點(diǎn),再?gòu)腖ist中查找根節(jié)點(diǎn)的子節(jié)點(diǎn);
import com.alibaba.fastjson.JSON; import com.ks.boot.entity.CityEntity; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import java.util.ArrayList; import java.util.List; public class TreeListDemo { List<CityEntity> cityEntities; /** * id name pid * 1 浙江 0 * 2 杭州 1 * 3 嘉興 1 * 4 南湖 3 * 5 桐鄉(xiāng) 3 * 6 余杭 2 * 7 西湖 2 * 8 云南 0 * 9 昆明 8 * 10 昭通 8 */ @BeforeEach public void init() { cityEntities = JSON.parseArray("[{\"id\":1,\"name\":\"浙江\",\"pid\":0},\n" + "{\"id\":2,\"name\":\"杭州\",\"pid\":1},\n" + "{\"id\":3,\"name\":\"嘉興\",\"pid\":1},\n" + "{\"id\":4,\"name\":\"南湖\",\"pid\":3},\n" + "{\"id\":5,\"name\":\"桐鄉(xiāng)\",\"pid\":3},\n" + "{\"id\":6,\"name\":\"余杭\",\"pid\":2},\n" + "{\"id\":7,\"name\":\"西湖\",\"pid\":2},\n" + "{\"id\":8,\"name\":\"云南\",\"pid\":0},\n" + "{\"id\":9,\"name\":\"昆明\",\"pid\":8},\n" + "{\"id\":10,\"name\":\"昭通\",\"pid\":8}]", CityEntity.class); } /** * 遞歸,List轉(zhuǎn)Tree * 主要思想:獲取所有根節(jié)點(diǎn)、頂級(jí)節(jié)點(diǎn),再?gòu)腖ist中查找根節(jié)點(diǎn)的子節(jié)點(diǎn); * 時(shí)間復(fù)雜度:N*(1+N)/2,O(N^2),因?yàn)檫f歸方法中,最好是List的第一元素就是要找的子節(jié)點(diǎn),最壞是 * List的最后一個(gè)元素是子節(jié)點(diǎn) */ @Test public void testList2Tree() { List<CityEntity> resultCities = new ArrayList<>(); for (CityEntity city : cityEntities) { if(0 == city.getPid()) { //獲取所有根節(jié)點(diǎn)、頂級(jí)節(jié)點(diǎn),再根據(jù)根節(jié)點(diǎn)進(jìn)行遞歸 CityEntity topCity = findChild(cityEntities, city); //此時(shí)的topCity已經(jīng)包含它的所有子節(jié)點(diǎn) resultCities.add(topCity); } } System.out.println(JSON.toJSONString(resultCities)); } /** * * @param cityEntities 在那個(gè)里面找 * @param curCity 找誰(shuí)的子節(jié)點(diǎn) * @return curCity的子節(jié)點(diǎn) */ public CityEntity findChild(List<CityEntity> cityEntities, CityEntity curCity) { for (CityEntity city : cityEntities) { if(curCity.getId().equals(city.getPid())) { if(null == curCity.getSubCityList()) { curCity.setSubCityList(new ArrayList<>()); } CityEntity subChild = findChild(cityEntities, city); //每次遞歸,都從頭開(kāi)始查找有沒(méi)有city的子節(jié)點(diǎn) curCity.getSubCityList().add(subChild); } } return curCity; } } public class CityEntity { private Long id; private String name; private Long pid; private List<CityEntity> subCityList; getter/setter }
轉(zhuǎn)換為Map
主要思想:
- 在雙層for的解法中,由于內(nèi)層for也需要遍歷以便List,造成時(shí)間復(fù)雜度上身為平方級(jí)
- 如果內(nèi)層for不需要遍歷完整的List,而是事先預(yù)處理到Map中,尋找時(shí)直接從Map中獲取,則時(shí)間復(fù)雜度降為L(zhǎng)ogN
import com.alibaba.fastjson2.JSON; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.stream.Collectors; public class TreeListDemo { List<CityEntity> cityEntities; /** * id name pid * 1 浙江 0 * 2 杭州 1 * 3 嘉興 1 * 4 南湖 3 * 5 桐鄉(xiāng) 3 * 6 余杭 2 * 7 西湖 2 * 8 云南 0 * 9 昆明 8 * 10 昭通 8 */ @BeforeEach public void init() { cityEntities = JSON.parseArray("[{\"id\":1,\"name\":\"浙江\",\"pid\":0},\n" + "{\"id\":2,\"name\":\"杭州\",\"pid\":1},\n" + "{\"id\":3,\"name\":\"嘉興\",\"pid\":1},\n" + "{\"id\":4,\"name\":\"南湖\",\"pid\":3},\n" + "{\"id\":5,\"name\":\"桐鄉(xiāng)\",\"pid\":3},\n" + "{\"id\":6,\"name\":\"余杭\",\"pid\":2},\n" + "{\"id\":7,\"name\":\"西湖\",\"pid\":2},\n" + "{\"id\":8,\"name\":\"云南\",\"pid\":0},\n" + "{\"id\":9,\"name\":\"昆明\",\"pid\":8},\n" + "{\"id\":10,\"name\":\"昭通\",\"pid\":8}]", CityEntity.class); } /** * 在雙層for的解法中,由于內(nèi)層for也需要遍歷以便List,造成時(shí)間復(fù)雜度上身為平方級(jí) * 如果內(nèi)層for不需要遍歷完整的List,而是事先預(yù)處理到Map中,尋找時(shí)直接從Map中獲取,則時(shí)間復(fù)雜度降為L(zhǎng)ogN */ @Test public void list2tree() { //收集每個(gè)PID下的節(jié)點(diǎn)為Map Map<Long, List<CityEntity>> cityMapByPid = cityEntities.stream().collect(Collectors.groupingBy(CityEntity::getPid)); List<CityEntity> resultCityList = new ArrayList<>(); for (CityEntity city : cityEntities) { if(0 == city.getPid()) { //根節(jié)點(diǎn)、頂點(diǎn) resultCityList.add(city); } List<CityEntity> citiesByPid = cityMapByPid.get(city.getId()); if(null != citiesByPid && citiesByPid.size() > 0) { //有子節(jié)點(diǎn) if(null == city.getSubCityList()) { city.setSubCityList(new ArrayList<>()); } city.getSubCityList().addAll(citiesByPid); //塞入 } } System.out.println(JSON.toJSONString(resultCityList)); } /** * 簡(jiǎn)化寫法:在收集到Map時(shí),對(duì)于沒(méi)有子節(jié)點(diǎn)的節(jié)點(diǎn),創(chuàng)建一個(gè)空的塞入到Map中 */ @Test public void list2tree4Simple() { List<CityEntity> resultCityList = new ArrayList<>(); //保存每個(gè)PID下的子節(jié)點(diǎn) Map<Long, List<CityEntity>> cityMapByPid = new HashMap<>(); for (CityEntity city : cityEntities) { //收集每個(gè)PID下的子節(jié)點(diǎn) //獲取當(dāng)前PID對(duì)應(yīng)的子節(jié)點(diǎn)List,如果沒(méi)有則創(chuàng)建一個(gè)空的List塞入 //這個(gè)設(shè)計(jì)得很巧妙 List<CityEntity> children = cityMapByPid.getOrDefault(city.getPid(), new ArrayList<>()); children.add(city); //插入當(dāng)前元素 cityMapByPid.put(city.getPid(), children); } for (CityEntity city : cityEntities) { if(0 == city.getPid()) { //根節(jié)點(diǎn)、頂點(diǎn) resultCityList.add(city); } city.setSubCityList(cityMapByPid.get(city.getId())); } System.out.println(JSON.toJSONString(resultCityList)); } }
棧
主要思想
收集根節(jié)點(diǎn)、頂級(jí)節(jié)點(diǎn),存入resultList,并且壓棧
循環(huán)出棧,棧元素Cur
- 找Cur的所有子元素為child
- 如果child不為空,則再壓入棧中。這一步的目的是,再一次找child的子元素
import com.alibaba.fastjson2.JSON; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import java.util.*; import java.util.stream.Collectors; public class TreeListDemo { List<CityEntity> cityEntities; /** * id name pid * 1 浙江 0 * 2 杭州 1 * 3 嘉興 1 * 4 南湖 3 * 5 桐鄉(xiāng) 3 * 6 余杭 2 * 7 西湖 2 * 8 云南 0 * 9 昆明 8 * 10 昭通 8 */ @BeforeEach public void init() { cityEntities = JSON.parseArray("[{\"id\":1,\"name\":\"浙江\",\"pid\":0},\n" + "{\"id\":2,\"name\":\"杭州\",\"pid\":1},\n" + "{\"id\":3,\"name\":\"嘉興\",\"pid\":1},\n" + "{\"id\":4,\"name\":\"南湖\",\"pid\":3},\n" + "{\"id\":5,\"name\":\"桐鄉(xiāng)\",\"pid\":3},\n" + "{\"id\":6,\"name\":\"余杭\",\"pid\":2},\n" + "{\"id\":7,\"name\":\"西湖\",\"pid\":2},\n" + "{\"id\":8,\"name\":\"云南\",\"pid\":0},\n" + "{\"id\":9,\"name\":\"昆明\",\"pid\":8},\n" + "{\"id\":10,\"name\":\"昭通\",\"pid\":8}]", CityEntity.class); } /** * 主要思想: * 收集根節(jié)點(diǎn)、頂級(jí)節(jié)點(diǎn),存入resultList,并且壓棧 * 循環(huán)出棧,棧元素Cur * 找Cur的所有子元素為child * 如果child不為空,則再壓入棧中。這一步的目的是,再一次找child的子元素 * 時(shí)間復(fù)雜度:N(過(guò)濾出所有跟節(jié)點(diǎn)) + 常數(shù)(出棧) * N(遍歷List找當(dāng)前節(jié)點(diǎn)的子元素) */ @Test public void list2tree() { List<CityEntity> resultCityList = new ArrayList<>(); Stack<CityEntity> stack = new Stack<>(); resultCityList = cityEntities.stream().filter(ele -> 0 == ele.getPid()).collect(Collectors.toList()); stack.addAll(resultCityList); //根節(jié)點(diǎn)、頂點(diǎn)入棧 while(!stack.isEmpty()) { CityEntity curCity = stack.pop(); List<CityEntity> child = cityEntities.stream().filter(ele -> curCity.getId().equals(ele.getPid())).collect(Collectors.toList()); if(!child.isEmpty()) { //這一步處理的原因是:當(dāng)沒(méi)有子元素,不顯示該個(gè)字段。流處理后沒(méi)有元素只會(huì)返回空List,不會(huì)返回null curCity.setSubCityList(child); } if(!child.isEmpty()) { stack.addAll(child); } } System.out.println(JSON.toJSONString(resultCityList)); } }
樹(shù)形List轉(zhuǎn)扁平List
遞歸
主要思想:遍歷樹(shù)節(jié)點(diǎn),一個(gè)樹(shù)節(jié)點(diǎn)如果有子樹(shù),則再次遞歸此子樹(shù),直到?jīng)]有子樹(shù)為止
import com.alibaba.fastjson2.JSON; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import java.util.ArrayList; import java.util.List; /** * id name pid * 1 浙江 0 * 2 杭州 1 * 3 嘉興 1 * 4 南湖 3 * 5 桐鄉(xiāng) 3 * 6 余杭 2 * 7 西湖 2 * 8 云南 0 * 9 昆明 8 * 10 昭通 8 */ public class ListTreeDemo { List<CityEntity> treeList; @BeforeEach public void init() { treeList = JSON.parseArray("[{\"id\":1,\"name\":\"浙江\",\"pid\":0,\"subCityList\":[" + "{\"id\":2,\"name\":\"杭州\",\"pid\":1,\"subCityList\":[{\"id\":6,\"name\":\"余杭\",\"pid\":2},{\"id\":7,\"name\":\"西湖\",\"pid\":2}]}," + "{\"id\":3,\"name\":\"嘉興\",\"pid\":1,\"subCityList\":[{\"id\":4,\"name\":\"南湖\",\"pid\":3},{\"id\":5,\"name\":\"桐鄉(xiāng)\",\"pid\":3}]}]}," + "{\"id\":8,\"name\":\"云南\",\"pid\":0,\"subCityList\":[{\"id\":9,\"name\":\"昆明\",\"pid\":8},{\"id\":10,\"name\":\"昭通\",\"pid\":8}]}]", CityEntity.class); } @Test public void tree2list() { List<CityEntity> resList = new ArrayList<>(); //這一層for的目的是:遍歷根節(jié)點(diǎn) for (CityEntity city : treeList) { reversion(city,resList); } System.out.println(JSON.toJSONString(resList)); } public void reversion(CityEntity curNode, List<CityEntity> resList) { resList.add(beanCopy(curNode)); List<CityEntity> subCityList = curNode.getSubCityList(); if(subCityList != null && !subCityList.isEmpty()) { for (CityEntity city : subCityList) { //遞歸尋找子節(jié)點(diǎn)的子節(jié)點(diǎn)們 reversion(city, resList); } } //遞歸的出口就是subCityList為null或者empty } private CityEntity beanCopy(CityEntity source) { CityEntity res = new CityEntity(); res.setId(source.getId()); res.setName(source.getName()); res.setPid(source.getPid()); return res; } }
棧
主要思想
依次遍歷樹(shù)形List,當(dāng)前節(jié)點(diǎn)為Cur
- 將Cur收集到某個(gè)存儲(chǔ)結(jié)果的List
- 如果Cur有子樹(shù),壓入某個(gè)棧中
依次彈出棧元素,當(dāng)前彈出的元素為StackSubTree
- 如果StackSubTree還有子樹(shù),繼續(xù)壓棧
- 如果StackSubTree沒(méi)有子樹(shù),則放入結(jié)果List
import com.alibaba.fastjson2.JSON; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import java.util.ArrayList; import java.util.List; import java.util.Stack; /** * id name pid * 1 浙江 0 * 2 杭州 1 * 3 嘉興 1 * 4 南湖 3 * 5 桐鄉(xiāng) 3 * 6 余杭 2 * 7 西湖 2 * 8 云南 0 * 9 昆明 8 * 10 昭通 8 */ public class ListTreeDemo { List<CityEntity> treeList; @BeforeEach public void init() { treeList = JSON.parseArray("[{\"id\":1,\"name\":\"浙江\",\"pid\":0,\"subCityList\":[" + "{\"id\":2,\"name\":\"杭州\",\"pid\":1,\"subCityList\":[{\"id\":6,\"name\":\"余杭\",\"pid\":2},{\"id\":7,\"name\":\"西湖\",\"pid\":2}]}," + "{\"id\":3,\"name\":\"嘉興\",\"pid\":1,\"subCityList\":[{\"id\":4,\"name\":\"南湖\",\"pid\":3},{\"id\":5,\"name\":\"桐鄉(xiāng)\",\"pid\":3}]}]}," + "{\"id\":8,\"name\":\"云南\",\"pid\":0,\"subCityList\":[{\"id\":9,\"name\":\"昆明\",\"pid\":8},{\"id\":10,\"name\":\"昭通\",\"pid\":8}]}]", CityEntity.class); } /** * 1. 依次遍歷樹(shù)形List,當(dāng)前節(jié)點(diǎn)為Cur * a) 將Cur收集到某個(gè)存儲(chǔ)結(jié)果的List * b) 如果Cur有子樹(shù),壓入某個(gè)棧中 * 2. 依次彈出棧元素,當(dāng)前彈出的元素為StackSubTree * a) 如果StackSubTree還有子樹(shù),繼續(xù)壓棧 * b) 如果StackSubTree沒(méi)有子樹(shù),則放入結(jié)果List */ @Test public void tree2list() { List<CityEntity> resList = new ArrayList<>(); Stack<List<CityEntity>> stack = new Stack<>(); for (CityEntity curCity : treeList) { resList.add(beanCopy(curCity)); if (curCity.getSubCityList() != null && !curCity.getSubCityList().isEmpty()) { stack.push(curCity.getSubCityList()); } } while (!stack.isEmpty()) { List<CityEntity> subTree = stack.pop(); for (CityEntity city : subTree) { if (city.getSubCityList() != null && !city.getSubCityList().isEmpty()) { stack.push(city.getSubCityList()); } else { resList.add(beanCopy(city)); } } } System.out.println(JSON.toJSONString(resList)); } private CityEntity beanCopy(CityEntity source) { CityEntity res = new CityEntity(); res.setId(source.getId()); res.setName(source.getName()); res.setPid(source.getPid()); return res; } }
到此這篇關(guān)于Java實(shí)現(xiàn)樹(shù)形List與扁平List互轉(zhuǎn)的示例代碼的文章就介紹到這了,更多相關(guān)Java樹(shù)形List與扁平List互轉(zhuǎn)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
JAVA獲取rabbitmq消息總數(shù)過(guò)程詳解
這篇文章主要介紹了JAVA獲取rabbitmq消息總數(shù)過(guò)程詳解,公司使用的是rabbitMQ,需要做監(jiān)控預(yù)警的job去監(jiān)控rabbitMQ里面的堆積消息個(gè)數(shù),如何使用rabbitMQ獲取監(jiān)控的隊(duì)列里面的隊(duì)列消息個(gè)數(shù)呢,需要的朋友可以參考下2019-07-07如何用Dos命令運(yùn)行Java版HelloWorld你知道嗎
這篇文章主要介紹了在dos窗口中編譯和運(yùn)行java文件的方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-08-08Spring Boot應(yīng)用配置常用相關(guān)視圖解析器詳解
這篇文章主要給大家介紹了關(guān)于Spring Boot應(yīng)用配置常用相關(guān)視圖解析器的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2018-12-12Quarkus中ConfigSourceInterceptor的加密配置實(shí)現(xiàn)
這篇文章主要為大家介紹Quarkus中ConfigSourceInterceptor加密配置的實(shí)現(xiàn)方式,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-02-02跳表的由來(lái)及Java實(shí)現(xiàn)詳解
跳表(Skip List)是一種基于鏈表的數(shù)據(jù)結(jié)構(gòu),它可以支持快速的查找、插入、刪除操作,本文主要來(lái)和大家講講跳表的由來(lái)與實(shí)現(xiàn),感興趣的小伙伴可以了解一下2023-06-06