Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add spliterator support in JsonNode #4865

Merged
merged 11 commits into from
Dec 31, 2024
29 changes: 28 additions & 1 deletion src/main/java/tools/jackson/databind/JsonNode.java
Original file line number Diff line number Diff line change
Expand Up @@ -1031,6 +1031,12 @@ public boolean hasNonNull(int index) {
@Override
public final Iterator<JsonNode> iterator() { return values(); }

/**
* Same as calling {@link #valueSpliterator()}.
*/
@Override
public final Spliterator<JsonNode> spliterator() { return valueSpliterator(); }

/**
* Method for accessing all value nodes of this Node, iff
* this node is a JSON Array or Object node. In case of Object node,
Expand All @@ -1041,6 +1047,18 @@ public Iterator<JsonNode> values() {
return ClassUtil.emptyIterator();
}

/**
* Method for accessing all value nodes of this Node, iff
* this node is a JSON Array or Object node. In case of Object node,
* field names (keys) are not included, only values.
* For other types of nodes, returns empty <code>Spliterator</code>.
*
* @since 3.0
*/
public Spliterator<JsonNode> valueSpliterator() {
return Spliterators.spliteratorUnknownSize(values(), Spliterator.ORDERED);
}

/**
* NOTE: This method is deprecated, use {@link #properties()} instead.
*
Expand All @@ -1051,7 +1069,7 @@ public Iterator<JsonNode> values() {
*/
@Deprecated // since 2.19
public Iterator<Map.Entry<String, JsonNode>> fields() {
return ClassUtil.emptyIterator();
return properties().iterator();
}

/**
Expand All @@ -1070,6 +1088,15 @@ public Set<Map.Entry<String, JsonNode>> properties() {
return Collections.emptySet();
}

/**
* @return {@code Spliterator} that can be used to traverse all key/value pairs
* for object nodes; empty spliterator (no contents) for other types
* @since 3.0
*/
public Spliterator<Map.Entry<String, JsonNode>> propertySpliterator() {
return properties().spliterator();
}

/**
* Returns a stream of all value nodes of this Node, iff
* this node is an {@code ArrayNode} or {@code ObjectNode}.
Expand Down
29 changes: 17 additions & 12 deletions src/main/java/tools/jackson/databind/node/ArrayNode.java
Original file line number Diff line number Diff line change
Expand Up @@ -217,18 +217,6 @@ public int size() {
@Override // since 2.10
public boolean isEmpty() { return _children.isEmpty(); }

/**
* {@inheritDoc}
*<p>
* NOTE: actual underlying implementation returns {@link java.util.ListIterator}
* from {@link java.util.List#listIterator()} that contains elements, since Jackson 2.18
* (before was only generic {@link java.util.Iterator}).
*/
@Override
public Iterator<JsonNode> values() {
return _children.listIterator();
}

@Override
public JsonNode get(int index) {
if ((index >= 0) && (index < _children.size())) {
Expand Down Expand Up @@ -268,6 +256,23 @@ public JsonNode required(int index) {
index, _children.size());
}

/**
* {@inheritDoc}
*<p>
* NOTE: actual underlying implementation returns {@link java.util.ListIterator}
* from {@link java.util.List#listIterator()} that contains elements, since Jackson 2.18
* (before was only generic {@link java.util.Iterator}).
*/
@Override
public Iterator<JsonNode> values() {
return _children.listIterator();
}

@Override
public Spliterator<JsonNode> valueSpliterator() {
return _children.spliterator();
}

@Override // @since 2.19
public Stream<JsonNode> valueStream() {
return _children.stream();
Expand Down
42 changes: 21 additions & 21 deletions src/main/java/tools/jackson/databind/node/ObjectNode.java
Original file line number Diff line number Diff line change
Expand Up @@ -230,11 +230,6 @@ public int size() {
@Override
public boolean isEmpty() { return _children.isEmpty(); }

@Override
public Iterator<JsonNode> values() {
return _children.values().iterator();
}

@Override
public JsonNode get(int index) { return null; }

Expand Down Expand Up @@ -277,25 +272,30 @@ public JsonNode required(String propertyName) {
/* Implementation of core JsonNode API: content traversal
/**********************************************************************
*/

/**
* @since 2.19
*/

@Override
public Iterator<JsonNode> values() {
return _children.values().iterator();
}

@Override
public Spliterator<JsonNode> valueSpliterator() {
return _children.values().spliterator();
}

@Override // @since 2.19
public Stream<JsonNode> valueStream() {
return _children.values().stream();
}

@Override
public Iterator<String> propertyNames() {
return _children.keySet().iterator();
}

/**
* Method to use for accessing all properties (with both names
* and values) of this JSON Object.
*
* @deprecated since 2.19 Use instead {@link #properties()}.
*/
@Deprecated // since 2.19
@Override
public Iterator<Map.Entry<String, JsonNode>> fields() {
return _children.entrySet().iterator();
public Spliterator<String> propertyNameSpliterator() {
return _children.keySet().spliterator();
}

/**
Expand All @@ -309,9 +309,9 @@ public Set<Map.Entry<String, JsonNode>> properties() {
return _children.entrySet();
}

@Override // @since 2.19
public Stream<JsonNode> valueStream() {
return _children.values().stream();
@Override
public Spliterator<Map.Entry<String, JsonNode>> propertySpliterator() {
return _children.entrySet().spliterator();
}

@Override // @since 2.19
Expand Down
4 changes: 3 additions & 1 deletion src/test/java/tools/jackson/databind/node/ArrayNodeTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,15 @@ public void testDirectCreation() throws Exception

assertStandardEquals(n);
assertFalse(n.values().hasNext());
assertEquals(0, n.valueSpliterator().estimateSize());
assertFalse(n.propertyNames().hasNext());
assertNotNull(n.propertyNameSpliterator());
assertTrue(n.isEmpty());
TextNode text = TextNode.valueOf("x");
n.add(text);
assertEquals(1, n.size());
assertFalse(n.isEmpty());
assertFalse(0 == n.hashCode());
assertNotEquals(0, n.hashCode());
assertTrue(n.values().hasNext());
// no field names for arrays
assertFalse(n.propertyNames().hasNext());
Expand Down