Skip to content

Commit

Permalink
streams - JSONObject and JSONArray implement iterable, add stream() m…
Browse files Browse the repository at this point in the history
…ethod to each class
  • Loading branch information
Sean Leary authored and Sean Leary committed Sep 4, 2023
1 parent c29d488 commit 252bfbb
Show file tree
Hide file tree
Showing 4 changed files with 115 additions and 11 deletions.
6 changes: 6 additions & 0 deletions src/main/java/org/json/JSONArray.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.stream.IntStream;
import java.util.stream.Stream;


/**
Expand Down Expand Up @@ -224,6 +226,10 @@ public JSONArray(int initialCapacity) throws JSONException {
this.myArrayList = new ArrayList<Object>(initialCapacity);
}

public Stream<Object> stream() {
return IntStream.range(0, length()).mapToObj(this::get);
}

@Override
public Iterator<Object> iterator() {
return this.myArrayList.iterator();
Expand Down
34 changes: 23 additions & 11 deletions src/main/java/org/json/JSONObject.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,11 @@
import java.lang.reflect.Modifier;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Collection;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.IdentityHashMap;
import java.util.Iterator;
import java.util.Locale;
import java.util.Map;
import java.util.*;
import java.util.Map.Entry;
import java.util.ResourceBundle;
import java.util.Set;
import java.util.function.Consumer;
import java.util.regex.Pattern;
import java.util.stream.Stream;

/**
* A JSONObject is an unordered collection of name/value pairs. Its external
Expand Down Expand Up @@ -81,7 +74,22 @@
* @author JSON.org
* @version 2016-08-15
*/
public class JSONObject {
public class JSONObject implements Iterable<String> {
@Override
public Iterator<String> iterator() {
return null;
}

@Override
public void forEach(Consumer<? super String> action) {
Iterable.super.forEach(action);
}

@Override
public Spliterator<String> spliterator() {
return Iterable.super.spliterator();
}

/**
* JSONObject.NULL is equivalent to the value that JavaScript calls null,
* whilst Java's null is equivalent to the value that JavaScript calls
Expand Down Expand Up @@ -461,6 +469,10 @@ protected JSONObject(int initialCapacity){
this.map = new HashMap<String, Object>(initialCapacity);
}

public Stream<String> stream() {
return keySet().stream();
}

/**
* Accumulate values under a key. It is similar to the put method except
* that if there is already an object stored under the key then a JSONArray
Expand Down
38 changes: 38 additions & 0 deletions src/test/java/org/json/junit/JSONArrayTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;

import org.json.JSONArray;
import org.json.JSONException;
Expand Down Expand Up @@ -66,6 +68,42 @@ public class JSONArrayTest {
"\"-1\""+
"]";

/**
* Tests the stream() API
*/
public void testStream() {
String data = "[\n" +
" {\n" +
" \"id\": 1,\n" +
" \"name\": \"Alice\",\n" +
" \"department\": \"HR\"\n" +
" },\n" +
" {\n" +
" \"id\": 2,\n" +
" \"name\": \"Bonnie\",\n" +
" \"department\": \"Engineering\"\n" +
" },\n" +
" {\n" +
" \"id\": 3,\n" +
" \"name\": \"Carol\",\n" +
" \"department\": \"Marketing\"\n" +
" }\n" +
" ]";
JSONArray jsonArray = new JSONArray(data);

// Get employees from the engineering dept
List<String> actualList = StreamSupport.stream(jsonArray.spliterator(), false)
.map(JSONObject.class::cast)
.filter(employee -> "Engineering".equals(employee.getString("department")))
.map(employee -> employee.getString("name"))
.collect(Collectors.toList());

List<String> expectedList = new ArrayList<>();
expectedList.add("Bonnie");
assertEquals(actualList, expectedList);
}


/**
* Tests that the similar method is working as expected.
*/
Expand Down
48 changes: 48 additions & 0 deletions src/test/java/org/json/junit/JSONObjectTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

import org.json.CDL;
import org.json.JSONArray;
Expand Down Expand Up @@ -72,6 +73,53 @@ public class JSONObjectTest {
*/
static final Pattern NUMBER_PATTERN = Pattern.compile("-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?");

/**
* Tests the stream api
*/
@Test
public void testStream() {
String data = "{\n" +
" \"employees\": [\n" +
" {\n" +
" \"id\": 1,\n" +
" \"name\": \"Alice\",\n" +
" \"department\": \"HR\"\n" +
" },\n" +
" {\n" +
" \"id\": 2,\n" +
" \"name\": \"Bonnie\",\n" +
" \"department\": \"Engineering\"\n" +
" },\n" +
" {\n" +
" \"id\": 3,\n" +
" \"name\": \"Carol\",\n" +
" \"department\": \"Marketing\"\n" +
" }\n" +
" ]\n" +
"}";

JSONObject jsonObject = new JSONObject(data);

// Get employees from the Engineering department
List<String> actualList = new ArrayList<>();

jsonObject.stream()
.filter(key -> key.startsWith("employees"))
.map(jsonObject::getJSONArray)
.flatMap(JSONArray::stream)
.map(JSONObject.class::cast)
.filter(employee -> "Engineering".equals(employee.getString("department")))
.map(employee -> employee.getString("name"))
.forEach(name -> actualList.add(name));

List<String> expectedList = new ArrayList<>();
expectedList.add("Bonnie");
assertEquals(expectedList, actualList);
}




/**
* Tests that the similar method is working as expected.
*/
Expand Down

0 comments on commit 252bfbb

Please sign in to comment.