1. 概述
在Java中使用JSON(JavaScript 對象表示法)通常涉及使用諸如Jackson之類的庫,該庫提供各種類來表示這種數據類型,例如JsonNode, ObjectNode, ArrayNode。
在本教程中,我們將 探索在不顯式將其轉換為ArrayNode的情況下,簡化對JsonNode上的數組操作的不同方法,這在Java中直接在我們的代碼中操縱數據時是必要的。
2. 理解 JsonNode 和 ArrayNode
JsonNode 是 Jackson 庫中的一個抽象類,代表 JSON 樹中的節點。它是所有節點的基類,能夠存儲不同類型的數據,包括對象、數組、字符串、數字、布爾值和 null 值。 JsonNode 實例是不可變的,這意味着我們不能設置它們的屬性。
ArrayNode 是 JsonNode 的一個特定類型,代表 JSON 數組。它擴展了 JsonNode 的功能,以包含處理數組的方法,例如添加、刪除和通過索引訪問元素。
3. 使用 JsonNode 的 get() 方法
通過使用 JsonNode 方法,我們可以將其轉換為 ArrayNode,而無需顯式地進行類型轉換。這種方法在我們需要對 JSON 數組中的每個元素執行特定操作或驗證時非常有用:
@Test
void givenJsonNode_whenUsingJsonNodeMethods_thenConvertToArrayNode() throws JsonProcessingException {
int count = 0;
String json = "{\"objects\": [\"One\", \"Two\", \"Three\"]}";
JsonNode arrayNode = new ObjectMapper().readTree(json).get("objects");
assertNotNull(arrayNode, "The 'objects' array should not be null");
assertTrue(arrayNode.isArray(), "The 'objects' should be an array");
if (arrayNode.isArray()) {
for (JsonNode objNode : arrayNode) {
assertNotNull(objNode, "Array element should not be null");
count++;
}
}
assertEquals(3, count, "The 'objects' array should have 3 elements");
}
這種方法還確保我們在嘗試迭代其元素之前正在處理數組結構,從而有助於防止與意外 JSON 結構相關的運行時錯誤。
4. 使用 createArrayNode()
在 Jackson 中,我們可以使用 createObjectNode()方法創建 JSON 對象。 類似地,我們也可以使用 ObjectMapper類中的 createArrayNode()方法創建 JSON 數組。 該方法 createArrayNode()將返回 ArrayNode類的引用:
@Test
void givenJsonNode_whenUsingCreateArrayNode_thenConvertToArrayNode() throws Exception {
ObjectMapper objectMapper = new ObjectMapper();
JsonNode originalJsonNode = objectMapper.readTree("{\"objects\": [\"One\", \"Two\", \"Three\"]}");
ArrayNode arrayNode = objectMapper.createArrayNode();
originalJsonNode.get("objects").elements().forEachRemaining(arrayNode::add);
assertEquals("[\"One\",\"Two\",\"Three\"]", arrayNode.toString());
}
這種方法在我們需要將 JSON 結構中的特定部分轉換為 ArrayNode,而無需顯式轉換時非常有用。 顯式創建 ArrayNode可以清楚地表明我們正在處理一個 Array,從而使代碼更具可讀性和表達力。
5. 使用 StreamSuppport 類
StreamSupport 是一個實用類,它提供靜態方法,用於為各種數據結構(包括集合、數組和專用迭代器)創建 Stream 和 Spliterator。
字符串已使用 ObjectMapper deserialize 為 JsonNode 對象。 在這裏,我們從 Spliterator 的 objects 數組創建 Stream,並將元素收集到 List<JsonNode> 中。
@Test
void givenJsonNode_whenUsingStreamSupport_thenConvertToArrayNode() throws Exception {
String json = "{\"objects\": [\"One\", \"Two\", \"Three\"]}";
JsonNode obj = new ObjectMapper().readTree(json);
List<JsonNode> objects = StreamSupport
.stream(obj.get("objects").spliterator(), false)
.collect(Collectors.toList());
assertEquals(3, objects.size(), "The 'objects' list should contain 3 elements");
JsonNode firstObject = objects.get(0);
assertEquals("One", firstObject.asText(), "The first element should be One");
}
這種方法在我們需要使用 Java Streams 以簡潔、表達力強的形式提取和處理 JSON 數組中的元素時非常有用。
6. 使用 迭代器
迭代器是多種遍歷集合的方法之一。 在這種方法中,我們使用迭代器來遍歷給定JSON結構中 對象數組的元素:
@Test
void givenJsonNode_whenUsingIterator_thenConvertToArrayNode() throws Exception {
String json = "{\"objects\": [\"One\", \"Two\", \"Three\"]}";
JsonNode datasets = new ObjectMapper().readTree(json);
Iterator<JsonNode> iterator = datasets.withArray("objects").elements();
int count = 0;
while (iterator.hasNext()) {
JsonNode dataset = iterator.next();
System.out.print(dataset.toString() + " ");
count++;
}
assertEquals(3, count, "The 'objects' list should contain 3 elements");
}
這種方法通過直接遍歷元素來減少了整體複雜性。 它為在迭代過程中自定義JSON元素的處理提供了一個簡單直接的機制。
7. 結論
在本教程中,我們探討了在不顯式地將 JsonNode 轉換為 ArrayNode 的情況下,簡化對 JsonNode 的數組操作的各種方法,應用於 Jackson。