icexmoon-tree

icexmoon-tree

一個輕量級的 Java 工具庫,提供樹形結構操作功能。

安裝

<dependency><groupId>cn.icexmoon</groupId><artifactId>icexmoon-tree</artifactId><version>1.0.0</version>
</dependency>

使用

構建樹

假設需要用樹構建的數據類型如下:

@Getter
@Setter
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
@ToString
public class Department implements Nodeable<Department> {@EqualsAndHashCode.Includeprivate Long id;private String name;private Long parentId;private Department parent;private List<Department> children;public Department(Long id, String name, Long parentId) {this.id = id;this.name = name;this.parentId = parentId;}
}

這里實現 Nodeable 接口并非必須,getter\setter\equals\hashcode 方法的實現也不是必須。

假設用 Department 構建了一些有樹層級關系的測試數據:

public static final List<Department> departments = List.of(new Department(1L, "宇宙科技有限公司", null),new Department(2L, "人事部", 1L),new Department(3L, "系統開發部", 1L),new Department(4L, "開發一部", 3L),new Department(5L, "開發二部", 3L),new Department(6L, "OA項目組", 4L));

這里 Department 實例的父子關系由 parentId 屬性指定,當然這也不是必須的,樹構建時關聯關系依賴于用戶提供的匿名函數,只要用戶將怎么關聯父子信息通過匿名函數告訴樹即可。

通過構造函數創建樹實例:

public static final Tree<Department> tree = new Tree<>(dept -> {Long id = dept.getId();List<Department> children = new ArrayList<>();for (Department department : departments) {if (department.getParentId() != null && department.getParentId().equals(id)) {children.add(department);}}return children;
}, departments::getFirst);

Tree的構造器需要提供兩個參數,都是匿名函數:

  • 匿名函數 GetDirectChildren:提供一個要包含在樹節點內的值(Value),返回其所有的子值(Child Value)。
  • 匿名函數 GetRoot:返回根節點的值。

銷毀樹

樹的節點信息是保存在內存中的(Tree 對象的 root 字段),因此如果樹創建時依賴的數據的父子關系發生變化,比如 department 表中新增了一個子部門或者刪除了一個子部門。需要調用 API 銷毀內存中的樹結構,以便再次訪問樹時能重新構建樹的父子關系。如果不這么做就可能導致一些 BUG。

銷毀樹:

tree.destroy();

遍歷樹

遍歷樹是一個常見操作,本項目支持通過一個匿名函數 Consumer 在遍歷樹時對節點執行一些操作:

tree.traversal(node -> {List<Node<Department>> allParents = tree.getAllParents(node);List<String> names = allParents.stream().map(n -> n.getValue().getName()).toList();String fullNames = String.join("/", names);System.out.println(fullNames);
});
  • getAllParents方法會返回指定節點的所有父節點,具體可以參考源碼。
  • 默認采用深度優先遍歷,提供其他 API 可以指定廣度遍歷或深度遍歷。

查找節點

有時候需要根據指定條件查找樹上的某個節點,可以:

Node<Department> findNode = tree.findNode(node -> node.getChildren() != null && node.getValue().getId() == 5);
System.out.println(findNode.getValue());

就像示例展示的,findNode方法接收一個 Predicate 類型的匿名函數作為匹配條件。

簡單樹拷貝

做前后端分離開發的時候,前端獲取到的樹不希望是類似:

{value: {id: 1,name: "宇宙科技有限公司",parentId: 0,//...},children[{value: {id: 2,name: "人事部",parentId: 1,//...},children:[...]}]
}

當然,直接使用是沒有任何問題的,但如果前端一定要使用類似下面的“簡單樹”(不包含 Value 這一層)結構:

{id: 1,name: "宇宙科技有限公司",parentId: 0,//...children[{id: 2,name: "人事部",parentId: 1,//...children:[...]}]
}

提供一個 API 可以方便獲取一個類似的簡單樹的拷貝:

Department rootDept = TreeUtil.getSimpleTreeCopy(TestData.tree, Department.class, false);
String jsonString = JSON.toJSONString(rootDept);
System.out.println(jsonString);
  • 因為涉及對象拷貝,所以需要提供一個 Class 對象用于反射。
  • 第三個參數可以控制返回的簡單樹中是否關聯父節點(parent字段),一般來說需要 JSON 后返回給前端的話必須是false,否則會導致 JSON 格式化工具循環遍歷進而堆棧溢出。
  • 要操作的數據類型必須有 parent 和 children 屬性以及對應的 Getter/Setter 方法,這里引入一個 Nodeable 接口進行限制,也就是說只有實現了該接口才能使用上面的 API。

其它操作

其它相關的操作和 API 可以直接查看源碼。

反饋&&建議

項目地址為 icexmoon/icexmoon-tree,你可以從這里查看源碼或提交建議。

版本更新記錄

1.0.0

初始版本。

1.0.1

簡化 POM 文件,移除不必要的依賴傳遞。修改 Readme 文件描述內容。

The End.

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/82412.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/82412.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/82412.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

機器學習在智能水泥基復合材料中的應用與實踐

“機器學習在智能水泥基復合材料中的應用與實踐” 課程 內容 機器學習基礎模型與復合材料研究融合 機器學習在復合材料中的應用概述機器學習用于復合材料研究的流程復合材料數據收集與數據預處理 實例&#xff1a;數據的收集和預處理 復合材料機器學習特征工程與選擇 實例&a…

微軟 Build 2025:開啟 AI 智能體時代的產業革命

在 2025 年 5 月 19 日的微軟 Build 開發者大會上&#xff0c;薩提亞?納德拉以 "我們已進入 AI 智能體時代" 的宣言&#xff0c;正式拉開了人工智能發展的新紀元。這場匯聚了奧特曼、黃仁勛、馬斯克三位科技領袖的盛會&#xff0c;不僅發布了 50 余項創新產品&#…

[Java惡補day6] 15. 三數之和

給你一個整數數組 nums &#xff0c;判斷是否存在三元組 [nums[i], nums[j], nums[k]] 滿足 i ! j、i ! k 且 j ! k &#xff0c;同時還滿足 nums[i] nums[j] nums[k] 0 。請你返回所有和為 0 且不重復的三元組。 注意&#xff1a;答案中不可以包含重復的三元組。 示例 1&a…

《黃帝內經》數學建模與形式化表征方式的重構

黃帝內經的數學概括&#xff1a;《黃帝內經》數學建模與形式化表征方式的重構 摘要&#xff1a;《黃帝內經》通過現代數學理論如動力系統、代數拓撲和隨機過程&#xff0c;被重構為一個形式化的人體健康模型。該模型包括陰陽動力學的微分幾何、五行代數的李群結構、經絡拓撲與同…

理論篇五:如何優化Webpack的打包速度

優化 Webpack 打包速度是提升前端開發效率的關鍵。以下是 10 種核心優化策略,涵蓋開發和生產環境,附帶具體配置和實測效果對比: 一、縮小文件搜索范圍 1. 指定解析路徑(Resolve) resolve: {extensions: [.js, .jsx],

[Windows] 游戲常用運行庫- Game Runtime Libraries Package(6.2.25.0409)

游戲常用運行庫 合集 整合了許多游戲會用到的運行庫&#xff0c;支持 Windows XP – Windows 11 系統&#xff0c;并且支持自動檢測系統勾選推薦的運行庫&#xff0c;方便快捷。 本版特點&#xff1a; By&#xff1a;mefcl 整合常見最新游戲所需運行庫 根據系統自動勾選推薦…

JDK8中的 Stream流式編程用法優化(工具類在文章最后)

Java從JDK8起提供了Stream流這個功能&#xff0c;于是項目里出現了大量基于Stream流的寫法。隨著項目的進行&#xff0c;慢慢的代碼中鋪天蓋地的都是下面的寫法&#xff1a; List<User> userList null;if (condition) {userList new ArrayList<>();userList.add(…

uni-app學習筆記十二-vue3中組件傳值(對象傳值)

一.單對象傳值 父組件定義對象的值 <template><view><UserInfo :obj"userinfo"></UserInfo></view> </template><script setup>import {ref} from "vue"const userinfo ref({name:"蛛兒",avatar:&…

UV-python環境管理工具 入門教程

在學習使用 MCP 的時候接觸到了 UV 這個環境管理工具&#xff0c;經過對比&#xff0c;發現它在諸多方面比 venv、conda 等工具更為出色&#xff0c;因此整理了這份簡單的入門學習筆記&#xff0c;希望能幫助大家快速上手。 介紹 UV 是一款集 Python 版本管理、虛擬環境創建與…

【漫話機器學習系列】277.梯度裁剪(Gradient Clipping)

【深度學習】什么是梯度裁剪&#xff08;Gradient Clipping&#xff09;&#xff1f;一張圖徹底搞懂&#xff01; 在訓練深度神經網絡&#xff0c;尤其是 RNN、LSTM、Transformer 這類深層結構時&#xff0c;你是否遇到過以下情況&#xff1a; 模型 loss 突然變成 NaN&#xf…

零基礎弄懂 ngx_http_slice_module分片緩存加速

一、為什么需要 Slice&#xff1f; 在 NGINX 反向代理或 CDN 場景中&#xff0c;大文件&#xff08;視頻、軟件包、鏡像等&#xff09;常因單體體積過大而令緩存命中率低、回源代價高。 ngx_http_slice_module 通過把一次完整響應拆分成 固定大小的字節塊&#xff08;Slice&am…

機器人強化學習入門學習筆記(三)

強化學習&#xff08;Reinforcement Learning, RL&#xff09;與監督學習不同——你不需要預先準備訓練數據集&#xff0c;而是要設計環境、獎勵函數&#xff0c;讓智能體通過交互不斷探索和學習。 &#x1f3af; 一、強化學習和訓練數據的關系 強化學習不依賴固定的數據集。它…

【python實戰】二手房房價數據分析與預測

個人主頁&#xff1a;大數據蟒行探索者 目錄 一、數據分析目標與任務 1.1背景介紹 1.2課程設計目標與任務 1.3研究方法與技術路線 二、數據預處理 2.1數據說明 2.2數據清洗 2.3數據處理 三、數據探索分析 四、數據分析模型 五、方案評估 摘要&#xff1a;隨著社會經…

Kotlin IR編譯器插件開發指南

在 Kotlin 中開發基于 IR&#xff08;Intermediate Representation&#xff09;的編譯器插件&#xff0c;可以深度定制語言功能或實現高級代碼轉換。以下是分步驟指南&#xff1a; 一、IR 編譯器插件基礎 IR 是什么&#xff1f; Kotlin 編譯器將源碼轉換為 IR 中間表示&#xf…

如何用 python 代碼復現 MATLAB simulink 的 PID

MATLAB在 Simulink 里做以下設置MATLAB 腳本調用示例 python 實現離散 PID 實現&#xff08;并行形式&#xff09; Simulink 中兩種 PID 結構&#xff08;并聯形式, I-形式&#xff09;下連續/離散時域里積分增益 I 的表示并聯&#xff08;Parallel&#xff09; vs 理想&#x…

黑馬點評--基于Redis實現共享session登錄

集群的session共享問題分析 session共享問題&#xff1a;多臺Tomcat無法共享session存儲空間&#xff0c;當請求切換到不同Tomcat服務時&#xff0c;原來存儲在一臺Tomcat服務中的數據&#xff0c;在其他Tomcat中是看不到的&#xff0c;這就導致了導致數據丟失的問題。 雖然系…

SkyWalking啟動失敗:OpenSearch分片數量達到上限的完美解決方案

?? 問題現象 SkyWalking OAP服務啟動時報錯: org.apache.skywalking.oap.server.library.module.ModuleStartException: java.lang.RuntimeException: {"error":{"root_cause":[{"type":"validation_exception", "reason&q…

向量數據庫選型實戰指南:Milvus架構深度解析與技術對比

導讀&#xff1a;隨著大語言模型和AI應用的快速普及&#xff0c;傳統數據庫在處理高維向量數據時面臨的性能瓶頸日益凸顯。當文檔經過嵌入模型處理生成768到1536維的向量后&#xff0c;傳統B-Tree索引的檢索效率會出現顯著下降&#xff0c;而現代應用對毫秒級響應的嚴苛要求使得…

MySQL#秘籍#一條SQL語句執行時間以及資源分析

背景 一條 SQL 語句的執行完&#xff0c;每個模塊耗時&#xff0c;不同資源(CPU/IO/IPC/SWAP)消耗情況我該如何知道呢&#xff1f;別慌俺有 - MySQL profiling 1. SQL語句執行前 - 開啟profiling -- profiling (0-關閉 1-開啟) -- 或者&#xff1a;show variables like prof…

【數據結構】實現方式、應用場景與優缺點的系統總結

以下是編程中常見的數據結構及其實現方式、應用場景與優缺點的系統總結&#xff1a; 一、線性數據結構 1. 數組 (Array) 定義&#xff1a;連續內存空間存儲相同類型元素。實現方式&#xff1a;int[] arr new int[10]; // Javaarr [0] * 10 # Python操作&#xff1a; 訪問&…