SpringBoot利用JSONPath實現(xiàn)高效處理JSON數(shù)據(jù)
在日常的后端開發(fā)工作中,我們經(jīng)常需要和 JSON 數(shù)據(jù)打交道,尤其是要從層級復(fù)雜的 JSON 結(jié)構(gòu)里精準提取特定字段。
傳統(tǒng)的處理方式,比如借助 Gson、Jackson 這類主流 JSON 解析庫的 API,雖然功能完備,但面對復(fù)雜路徑的字段提取時,寫出來的代碼往往又長又亂,后期維護起來也特別費勁。
今天就給大家分享一個更優(yōu)雅的解決方案 —— JSONPath,它就好比 JSON 領(lǐng)域的 XPath,能讓我們用簡潔的路徑表達式,輕松定位和提取 JSON 里的數(shù)據(jù)。
什么是 JSONPath
JSONPath 是一種專門用于從 JSON 文檔中提取指定數(shù)據(jù)的查詢語言。
它的語法簡潔又直觀,和 JavaScript 訪問對象屬性的方式很相似,能快速定位 JSON 結(jié)構(gòu)里的任意數(shù)據(jù)節(jié)點。
核心語法說明:
$:代表 JSON 結(jié)構(gòu)的根節(jié)點@:代表當前節(jié)點.:子節(jié)點操作符..:遞歸下降,可匹配任意深度的節(jié)點*:通配符,匹配所有成員/數(shù)組元素[]:下標運算符,用于數(shù)組索引[start:end]:數(shù)組切片,截取指定范圍的數(shù)組元素[?()]:過濾表達式,按條件篩選數(shù)據(jù)
Spring Boot 集成 JSONPath
想要在 Spring Boot 項目中使用 JSONPath,首先需要在 pom.xml 中引入對應(yīng)的依賴:
<!-- JSONPath 核心依賴 -->
<dependency>
<groupId>com.jayway.jsonpath</groupId>
<artifactId>json-path</artifactId>
<version>2.9.0</version>
</dependency>先準備一個示例 JSON 數(shù)據(jù),方便后續(xù)演示:
{
"store": {
"book": [
{
"category": "reference",
"author": "Nigel Rees",
"title": "Sayings of the Century",
"price": 8.95
},
{
"category": "fiction",
"author": "Evelyn Waugh",
"title": "Sword of Honour",
"price": 12.99
},
{
"category": "fiction",
"author": "Herman Melville",
"title": "Moby Dick",
"isbn": "0-553-21311-3",
"price": 8.99
}
],
"bicycle": {
"color": "red",
"price": 19.95
}
}
}基礎(chǔ)使用示例(添加詳細注解):
import com.jayway.jsonpath.DocumentContext;
import com.jayway.jsonpath.JsonPath;
import com.jayway.jsonpath.PathNotFoundException;
import java.util.List;
import java.util.Map;
public class JsonPathExample {
// 示例JSON字符串(實際使用時替換為真實數(shù)據(jù))
private String json = "{\"store\":{\"book\":[{\"category\":\"reference\",\"author\":\"Nigel Rees\",\"title\":\"Sayings of the Century\",\"price\":8.95},{\"category\":\"fiction\",\"author\":\"Evelyn Waugh\",\"title\":\"Sword of Honour\",\"price\":12.99},{\"category\":\"fiction\",\"author\":\"Herman Melville\",\"title\":\"Moby Dick\",\"isbn\":\"0-553-21311-3\",\"price\":8.99}],\"bicycle\":{\"color\":\"red\",\"price\":19.95}}}";
public void testReadJson() {
// 1. 提取所有書籍的作者
List<String> authors = JsonPath.parse(json)
.read("$.store.book[*].author");
// 2. 提取第一本書的價格
Double price = JsonPath.parse(json)
.read("$.store.book[0].price");
// 3. 過濾價格低于10元的書籍
List<Map<String, Object>> cheapBooks = JsonPath.parse(json)
.read("$.store.book[?(@.price < 10)]");
// 4. 提取最后一本書的完整信息
Map<String, Object> lastBook = JsonPath.parse(json)
.read("$.store.book[-1]");
}
}在 Spring Boot 接口中實戰(zhàn)使用:
import com.jayway.jsonpath.JsonPath;
import com.jayway.jsonpath.PathNotFoundException;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
import java.util.Map;
@RestController
public class BookController {
/**
* 提取JSON中的書籍標題和指定價格區(qū)間的書籍
* @param jsonString 傳入的JSON字符串
* @return 包含標題和過濾后書籍的響應(yīng)
*/
@PostMapping("/extractBookData")
public ResponseEntity<?> extractData(@RequestBody String jsonString) {
try {
// 提取所有書籍的標題
List<String> titles = JsonPath.parse(jsonString)
.read("$.store.book[*].title");
// 過濾價格大于等于8且小于等于15的書籍(補全原代碼語法錯誤)
List<Map<String, Object>> books = JsonPath.parse(jsonString)
.read("$.store.book[?(@.price >= 8 && @.price <= 15)]");
return ResponseEntity.ok(Map.of(
"titles", titles,
"filteredBooks", books
));
} catch (PathNotFoundException e) {
// 路徑不存在時返回錯誤提示
return ResponseEntity.badRequest()
.body("JSON路徑不存在: " + e.getMessage());
}
}
/**
* 提取所有書籍的作者
* @param jsonData 傳入的JSON字符串
* @return 作者列表
*/
@PostMapping("/getBookAuthors")
public ResponseEntity<?> getAuthors(@RequestBody String jsonData) {
List<String> authors = JsonPath.parse(jsonData)
.read("$.store.book[*].author");
return ResponseEntity.ok(authors);
}
}自定義 JSONPath 配置(適配不同業(yè)務(wù)場景):
import com.jayway.jsonpath.Configuration;
import com.jayway.jsonpath.Option;
public class JsonPathConfig {
/**
* 構(gòu)建自定義的JSONPath配置
* @return 配置實例
*/
public Configuration jsonPathConfiguration() {
return Configuration.builder()
// 抑制異常(路徑不存在時不拋異常)
.options(Option.SUPPRESS_EXCEPTIONS)
// 路徑葉子節(jié)點不存在時返回null
.options(Option.DEFAULT_PATH_LEAF_TO_NULL)
// 始終返回List類型(即使結(jié)果只有一個元素)
.options(Option.ALWAYS_RETURN_LIST)
// 開啟緩存(提升重復(fù)路徑查詢性能)
.options(Option.CACHE)
.build();
}
}優(yōu)化 JSONPath 查詢性能(緩存與預(yù)編譯):
import com.jayway.jsonpath.Configuration;
import com.jayway.jsonpath.JsonPath;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class JsonPathCacheService {
// 緩存容器,存儲已解析的JSON數(shù)據(jù)(線程安全)
private final Map<String, Object> cache = new ConcurrentHashMap<>();
/**
* 帶緩存的JSONPath讀?。ɑA(chǔ)版)
* @param json 原始JSON字符串
* @param path JSONPath表達式
* @return 提取的數(shù)據(jù)
*/
public Object readWithCache(String json, String path) {
return JsonPath.using(Configuration.defaultConfiguration())
.parse(json)
.read(path);
}
// 預(yù)編譯常用的JSONPath表達式(避免重復(fù)編譯,提升性能)
private final JsonPath compiledPath = JsonPath.compile("$.store.book[*]");
/**
* 使用預(yù)編譯路徑查詢所有書籍
* @param json 原始JSON字符串
* @return 書籍列表
*/
public List<Map<String, Object>> readOptimized(String json) {
return compiledPath.read(json);
}
}對接外部 API 并提取數(shù)據(jù):
import com.jayway.jsonpath.JsonPath;
import org.springframework.web.client.RestTemplate;
import java.util.List;
public class ExternalApiService {
private final RestTemplate restTemplate;
// 構(gòu)造器注入RestTemplate
public ExternalApiService(RestTemplate restTemplate) {
this.restTemplate = restTemplate;
}
/**
* 調(diào)用外部API并通過JSONPath提取數(shù)據(jù)
* @param url 外部API地址
* @param jsonPath JSONPath表達式
* @return 提取的數(shù)據(jù)列表
*/
public List<Object> extractFromExternalApi(String url, String jsonPath) {
// 調(diào)用外部API獲取JSON響應(yīng)
String response = restTemplate.getForObject(url, String.class);
// 解析并提取指定路徑的數(shù)據(jù)
return JsonPath.parse(response).read(jsonPath);
}
}常用過濾表達式示例:
// 1. 價格大于10的書籍 // $.store.book[?(@.price > 10)] // 2. 分類為fiction的書籍 // $.store.book[?(@.category == 'fiction')] // 3. 包含isbn字段的書籍 // $.store.book[?(@.isbn)] // 4. 作者名稱包含Melville的書籍(正則匹配) // $.store.book[?(@.author =~ /.*Melville.*/)] // 5. 價格低于10且分類為fiction的書籍 // $.store.book[?(@.price < 10 && @.category == 'fiction')]
除了 Jayway JsonPath,市面上主流的 JSON 處理庫也都有各自的 JSONPath 或類似功能實現(xiàn),下面給大家逐一介紹。
FastJSON - 內(nèi)置原生 JSONPath 支持
FastJSON 作為國內(nèi)常用的 JSON 解析庫,內(nèi)置了完善的 JSONPath 功能,使用起來非常便捷。
首先引入 FastJSON 依賴:
<dependency>
<groupId>com.alibaba.fastjson2</groupId>
<artifactId>fastjson2</artifactId>
<version>2.0.53</version>
</dependency>基礎(chǔ)使用示例:
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONPath;
import com.alibaba.fastjson2.JSONObject;
import java.util.List;
public class FastJsonPathExample {
// 示例JSON字符串
private String json = "{\"store\":{\"book\":[{\"category\":\"reference\",\"author\":\"Nigel Rees\",\"title\":\"Sayings of the Century\",\"price\":8.95},{\"category\":\"fiction\",\"author\":\"Evelyn Waugh\",\"title\":\"Sword of Honour\",\"price\":12.99},{\"category\":\"fiction\",\"author\":\"Herman Melville\",\"title\":\"Moby Dick\",\"isbn\":\"0-553-21311-3\",\"price\":8.99}],\"bicycle\":{\"color\":\"red\",\"price\":19.95}}}";
public void testFastJsonPath() {
// 將JSON字符串解析為JSONObject
JSONObject object = JSON.parseObject(json);
// 1. 提取所有書籍的作者
List<String> authors = (List<String>) JSONPath.eval(object, "$.store.book[*].author");
// 2. 提取第一本書的價格
Double price = (Double) JSONPath.eval(object, "$.store.book[0].price");
// 3. 過濾價格低于10的書籍
List<JSONObject> books = (List<JSONObject>) JSONPath.eval(object, "$.store.book[?(@.price < 10)]");
// 4. 獲取書籍數(shù)組的長度
Integer size = (Integer) JSONPath.eval(object, "$.store.book.size()");
// 5. 提取包含isbn字段的書籍
List<JSONObject> booksWithIsbn = (List<JSONObject>) JSONPath.eval(object, "$.store.book[?(@.isbn)]");
}
}FastJSON 提供了多種查詢方式,適配不同的業(yè)務(wù)場景:
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONPath;
import com.alibaba.fastjson2.JSONObject;
import java.util.List;
public class FastJsonPathQueryExample {
// 解析后的JSONObject對象
private JSONObject object = JSON.parseObject("{\"store\":{\"book\":[{\"category\":\"reference\",\"author\":\"Nigel Rees\",\"title\":\"Sayings of the Century\",\"price\":8.95},{\"category\":\"fiction\",\"author\":\"Evelyn Waugh\",\"title\":\"Sword of Honour\",\"price\":12.99},{\"category\":\"fiction\",\"author\":\"Herman Melville\",\"title\":\"Moby Dick\",\"isbn\":\"0-553-21311-3\",\"price\":8.99}],\"bicycle\":{\"color\":\"red\",\"price\":19.95}}}");
public void testDifferentQueryMethods() {
// 方式1:直接調(diào)用eval方法(最簡潔)
List<String> authors1 = (List<String>) JSONPath.eval(object, "$.store.book[*].author");
// 方式2:先創(chuàng)建Path對象,再調(diào)用extract方法
JSONPath path = JSONPath.of("$.store.book[*].author");
List<String> authors2 = (List<String>) path.extract(object);
// 方式3:預(yù)編譯Path表達式(重復(fù)使用時推薦)
JSONPath compiledPath = JSONPath.compile("$.store.book[*].author");
List<String> authors3 = (List<String>) compiledPath.eval(object);
// 修改指定路徑的值
JSONPath pricePath = JSONPath.of("$.store.book[0].price");
pricePath.set(object, 88.88);
// 判斷指定路徑是否存在
boolean hasBook = JSONPath.contains(object, "$.store.book");
boolean hasIsbn = JSONPath.contains(object, "$.store.book[2].isbn");
// 獲取數(shù)組長度(兩種方式)
Integer arraySize = (Integer) JSONPath.eval(object, "$.store.book.size()");
JSONPath sizePath = JSONPath.of("$.store.book.size()");
Integer size = (Integer) sizePath.eval(object);
}
}FastJSON 的 JSONPath 一大亮點是支持修改 JSON 數(shù)據(jù):
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONPath;
import com.alibaba.fastjson2.JSONObject;
public class FastJsonPathModifyExample {
public void testJsonPathSet() {
// 解析JSON字符串為可修改的JSONObject
JSONObject object = JSON.parseObject("{\"store\":{\"book\":[{\"category\":\"reference\",\"author\":\"Nigel Rees\",\"title\":\"Sayings of the Century\",\"price\":8.95},{\"category\":\"fiction\",\"author\":\"Evelyn Waugh\",\"title\":\"Sword of Honour\",\"price\":12.99},{\"category\":\"fiction\",\"author\":\"Herman Melville\",\"title\":\"Moby Dick\",\"isbn\":\"0-553-21311-3\",\"price\":8.99}],\"bicycle\":{\"color\":\"red\",\"price\":19.95}}}");
// 1. 修改第一本書的價格
JSONPath.set(object, "$.store.book[0].price", 99.99);
// 2. 修改自行車的顏色
JSONPath.set(object, "$.store.bicycle.color", "blue");
// 3. 批量修改所有書籍的價格
JSONPath.set(object, "$.store.book[*].price", 15.88);
// 4. 修改包含isbn字段的書籍分類
JSONPath.set(object, "$.store.book[?(@.isbn)].category", "classic");
// 5. 給第一本書新增出版社字段
JSONPath.set(object, "$.store.book[0].publisher", "Tech Press");
// 6. 向書籍數(shù)組中添加新書籍
JSONArray bookArray = (JSONArray) JSONPath.eval(object, "$.store.book");
bookArray.add(JSON.parseObject("{\"title\":\"New Book\",\"price\":9.99}"));
// 7. 刪除自行車節(jié)點
JSONPath.remove(object, "$.store.bicycle");
// 打印修改后的JSON(格式化輸出)
System.out.println(JSON.toJSONString(object, true));
}
}FastJSON 還支持常用的數(shù)組操作:
// 獲取數(shù)組長度 // Integer size = (Integer) JSONPath.eval(object, "$.store.book.size()"); // 獲取數(shù)組第一個元素 // Object first = JSONPath.eval(object, "$.store.book.first()"); // 獲取數(shù)組最后一個元素 // Object last = JSONPath.eval(object, "$.store.book.last()"); // 獲取數(shù)組所有值的集合 // Collection<Object> values = (Collection<Object>) JSONPath.eval(object, "$.store.book.values()");
Jackson - JsonPointer / Jackson JsonPath
Jackson 是 Spring Boot 默認集成的 JSON 解析庫,它原生支持 JsonPointer(遵循 RFC 6901 標準),但這并不是完整的 JSONPath 實現(xiàn)。
如果需要使用完整的 JSONPath 功能,可參考以下兩種方式:
方式1:使用原生 JsonPointer(適合簡單場景)
先引入 Jackson 核心依賴:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.18.2</version>
</dependency>使用示例:
import com.fasterxml.jackson.core.JsonPointer;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
public class JacksonJsonPointerExample {
// 示例JSON字符串
private String json = "{\"store\":{\"book\":[{\"category\":\"reference\",\"author\":\"Nigel Rees\",\"title\":\"Sayings of the Century\",\"price\":8.95},{\"category\":\"fiction\",\"author\":\"Evelyn Waugh\",\"title\":\"Sword of Honour\",\"price\":12.99},{\"category\":\"fiction\",\"author\":\"Herman Melville\",\"title\":\"Moby Dick\",\"isbn\":\"0-553-21311-3\",\"price\":8.99}],\"bicycle\":{\"color\":\"red\",\"price\":19.95}}}";
// Jackson核心解析器
private ObjectMapper mapper = new ObjectMapper();
public void testJsonPointer() throws Exception {
// 將JSON字符串解析為JsonNode(不可變節(jié)點)
JsonNode root = mapper.readTree(json);
// 1. 構(gòu)建JsonPointer并提取第一本書的作者
JsonPointer ptr = JsonPointer.compile("/store/book/0/author");
JsonNode authorNode = root.at(ptr);
String author = authorNode.asText();
// 2. 直接通過路徑字符串提取第二本書的標題
String title = root.at("/store/book/1/title").asText();
// 3. 提取自行車的價格
Double price = root.at("/store/bicycle/price").asDouble();
}
}JsonPointer 局限性:
- 語法簡單,僅支持基礎(chǔ)的路徑訪問,不支持通配符、過濾表達式;
- 無法一次性獲取多個節(jié)點的值;
- 不支持數(shù)組切片操作;
方式2:結(jié)合 Jayway JsonPath(適合復(fù)雜場景)
依賴和之前一致,只需新增 Jackson 適配配置:
import com.jayway.jsonpath.Configuration;
import com.jayway.jsonpath.JsonPath;
import com.jayway.jsonpath.spi.json.JacksonJsonNodeJsonProvider;
import com.jayway.jsonpath.spi.mapper.JacksonMappingProvider;
import java.util.List;
public class JacksonJsonPathExample {
// 示例JSON字符串
private String json = "{\"store\":{\"book\":[{\"category\":\"reference\",\"author\":\"Nigel Rees\",\"title\":\"Sayings of the Century\",\"price\":8.95},{\"category\":\"fiction\",\"author\":\"Evelyn Waugh\",\"title\":\"Sword of Honour\",\"price\":12.99},{\"category\":\"fiction\",\"author\":\"Herman Melville\",\"title\":\"Moby Dick\",\"isbn\":\"0-553-21311-3\",\"price\":8.99}],\"bicycle\":{\"color\":\"red\",\"price\":19.95}}}";
// 構(gòu)建適配Jackson的JSONPath配置
private Configuration configuration = Configuration.builder()
.jsonProvider(new JacksonJsonNodeJsonProvider())
.mappingProvider(new JacksonMappingProvider())
.build();
public void testJacksonJsonPath() {
// 提取所有書籍的作者(使用Jackson作為底層解析器)
List<String> authors = JsonPath.using(configuration)
.parse(json)
.read("$.store.book[*].author");
}
}Gson - 無原生 JSONPath 支持
Gson 是 Google 推出的 JSON 解析庫,它本身沒有提供 JSONPath 相關(guān)功能,這也是 Gson 相比其他庫的一個短板。
如果項目中已經(jīng)使用了 Gson,建議搭配 Jayway JsonPath 來彌補這個不足。
首先引入依賴:
<!-- Gson核心依賴 -->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.11.0</version>
</dependency>
<!-- JSONPath依賴 -->
<dependency>
<groupId>com.jayway.jsonpath</groupId>
<artifactId>json-path</artifactId>
<version>2.9.0</version>
</dependency>使用示例:
import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.jayway.jsonpath.JsonPath;
import java.util.List;
public class GsonJsonPathExample {
// Gson解析器實例
private Gson gson = new Gson();
// 示例JSON字符串
private String json = "{\"store\":{\"book\":[{\"category\":\"reference\",\"author\":\"Nigel Rees\",\"title\":\"Sayings of the Century\",\"price\":8.95},{\"category\":\"fiction\",\"author\":\"Evelyn Waugh\",\"title\":\"Sword of Honour\",\"price\":12.99},{\"category\":\"fiction\",\"author\":\"Herman Melville\",\"title\":\"Moby Dick\",\"isbn\":\"0-553-21311-3\",\"price\":8.99}],\"bicycle\":{\"color\":\"red\",\"price\":19.95}}}";
public void testGsonWithJsonPath() {
// 1. 使用JSONPath提取所有書籍的作者
List<String> authors = JsonPath.parse(json)
.read("$.store.book[*].author");
// 2. 將提取的結(jié)果轉(zhuǎn)換為Gson的JsonElement(適配Gson生態(tài))
JsonElement element = gson.toJsonTree(authors);
}
}三種方案對比
| 特性 | FastJSON | Jackson + JsonPointer | Jayway JsonPath |
|---|---|---|---|
| JSONPath 支持 | 原生完整支持 | 僅JsonPointer(基礎(chǔ)) | 完整支持 |
| 過濾表達式 | 支持 | 不支持 | 支持 |
| 通配符 | 支持 | 不支持 | 支持 |
| 性能 | 優(yōu)秀 | 優(yōu)秀 | 良好 |
| 生態(tài)穩(wěn)定性 | 曾出現(xiàn)安全漏洞 | 最穩(wěn)定 | 社區(qū)活躍 |
| Spring Boot 集成 | 需手動配置 | 默認集成 | 需添加依賴 |
選型建議
- 已有 FastJSON 項目:直接使用 FastJSON 內(nèi)置的 JSONPath 功能,無需額外引入依賴;
- 使用 Jackson 的項目:簡單的字段提取場景用原生 JsonPointer 即可,復(fù)雜的過濾、批量提取場景建議引入 Jayway JsonPath;
- 使用 Gson 的項目:搭配 Jayway JsonPath 使用,彌補 Gson 無 JSONPath 的短板;
- 新項目:推薦使用 Jackson + Jayway JsonPath 組合,兼顧生態(tài)穩(wěn)定性和功能完整性;
JSONPath 是處理 JSON 數(shù)據(jù)的高效工具,通過簡潔的路徑表達式,能輕松實現(xiàn)復(fù)雜字段提取、條件過濾和動態(tài)查詢。
在 Spring Boot 項目中集成 JSONPath,能大幅簡化 JSON 處理代碼,提升代碼的可讀性和可維護性,是處理復(fù)雜 JSON 結(jié)構(gòu)、對接第三方 API 數(shù)據(jù)的優(yōu)質(zhì)技術(shù)方案。
以上就是SpringBoot利用JSONPath實現(xiàn)高效處理JSON數(shù)據(jù)的詳細內(nèi)容,更多關(guān)于SpringBoot JSONPath處理JSON數(shù)據(jù)的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Java采用循環(huán)鏈表結(jié)構(gòu)求解約瑟夫問題
這篇文章主要介紹了Java采用循環(huán)鏈表結(jié)構(gòu)求解約瑟夫問題的解決方法,是很多Java面試環(huán)節(jié)都會遇到的經(jīng)典考題,這里詳細給出了約瑟夫問題的原理及Java解決方法,是非常經(jīng)典的應(yīng)用實例,具有一定的參考借鑒價值,需要的朋友可以參考下2014-12-12
Java中StringBuilder與StringBuffer使用及源碼解讀
我們前面學習的String就屬于不可變字符串,因為理論上一個String字符串一旦定義好,其內(nèi)容就不可再被改變,但實際上,還有另一種可變字符串,包括StringBuilder和StringBuffer兩個類,那可變字符串有什么特點,又怎么使用呢,接下來就請大家跟我一起來學習吧2023-05-05
生產(chǎn)環(huán)境NoHttpResponseException異常排查解決記錄分析
這篇文章主要為大家介紹了生產(chǎn)環(huán)境NoHttpResponseException異常排查解決記錄分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-10-10
Java中synchronized和ReentrantLock的區(qū)別對比
這篇文章主要介紹了Java中synchronized和ReentrantLock的區(qū)別對比,synchronized和ReentrantLock是Java中兩種主要的線程同步機制,它們都能保證線程安全,但在實現(xiàn)和功能上有明顯區(qū)別,需要的朋友可以參考下本篇介紹2026-01-01
Java超詳細教你寫一個斗地主洗牌發(fā)牌系統(tǒng)
這篇文章主要介紹了怎么用Java來你寫一個斗地主種洗牌和發(fā)牌的功能,斗地主相信大家都知道,同時也知道每一局都要洗牌打亂順序再發(fā)牌,本篇我們就來實現(xiàn)這個功能,感興趣的朋友跟隨文章往下看看吧2022-03-03

