Streaming is On Mates
Feature Description
JSONObject.toStream(): New public method that returns a sequential Stream traversing every node (objects, arrays, and primitive leaves) in depth-first order. Enables fluent chaining of all Stream operations (forEach, map, filter, collect, etc.).
JSONNode utility class : Lightweight record delivered by the stream, exposing• getKey() & getValue()• getPath() (JSON-pointer-style, e.g. root/arr[0]/id)• getParent() reference• helpers isLeaf(), typed getters (getStringValue(), getIntValue() …) and updateValue() for in-place mutation of the underlying JSONObject.
JSONNodeSpliterator (internal) : Depth-first spliterator powering toStream(); protects against circular references, includes array indices in paths, and delivers nodes lazily (small memory footprint).
Extensive JUnit coverage : Three new test suites (> 100 assertions) proving full traversal, stream chaining (filter → map → collect), in-place updates, path correctness, and leaf detection—all existing JSON-java tests still pass.
No breaking changes. All additions are backward-compatible; existing codebases compile unchanged. Requires Java 8+ (Streams API).
🔧 Quick Example
JSONObject obj = XML.toJSONObject( "<Books>" + "<book><title>A</title><price>10</price></book>" + "<book><title>B</title><price>20</price></book>" + "</Books>");// Collect all titles
List<String> titles = obj.toStream()
.filter(n -> "title".equals(n.getKey()))
.map(JSONNode::getStringValue)
.collect(Collectors.toList());
// Discount every numeric price by 25 %
obj.toStream()
.filter(n -> "price".equals(n.getKey()) && n.getValue() instanceof Number)
.forEach(n -> n.updateValue(((Number) n.getValue()).doubleValue() * 0.75));