diff --git a/gson/src/main/java/com/google/gson/JsonArray.java b/gson/src/main/java/com/google/gson/JsonArray.java index 10b94c0dc1..b5174155a0 100644 --- a/gson/src/main/java/com/google/gson/JsonArray.java +++ b/gson/src/main/java/com/google/gson/JsonArray.java @@ -23,6 +23,8 @@ import java.util.ArrayList; import java.util.Iterator; import java.util.List; +import java.util.stream.Collector; +import org.jspecify.annotations.Nullable; /** * A class representing an array type in JSON. An array is a list of {@link JsonElement}s each of @@ -40,6 +42,24 @@ * @author Joel Leitch */ public final class JsonArray extends JsonElement implements Iterable { + private static final Collector<@Nullable JsonElement, JsonArray, JsonArray> COLLECTOR = + Collector.of( + JsonArray::new, + JsonArray::add, + (left, right) -> { + left.addAll(right); + return left; + }); + + /** + * Returns a {@link Collector} that accumulates {@link JsonElement}s into a {@code JsonArray}. + * + * @since $next-version$ + */ + public static Collector<@Nullable JsonElement, ?, JsonArray> collector() { + return COLLECTOR; + } + private final ArrayList elements; /** Creates an empty JsonArray. */ diff --git a/gson/src/test/java/com/google/gson/JsonArrayTest.java b/gson/src/test/java/com/google/gson/JsonArrayTest.java index e6e60070af..3a217c7a44 100644 --- a/gson/src/test/java/com/google/gson/JsonArrayTest.java +++ b/gson/src/test/java/com/google/gson/JsonArrayTest.java @@ -22,6 +22,8 @@ import com.google.common.testing.EqualsTester; import com.google.gson.common.MoreAsserts; import java.math.BigInteger; +import java.util.stream.IntStream; +import java.util.stream.Stream; import org.junit.Test; /** @@ -354,4 +356,30 @@ public void testToString() { array.add(nestedObject); assertThat(array.toString()).isEqualTo("[null,NaN,\"a\\u0000\",[\"\\\"\"],{\"n\\u0000\":1}]"); } + + @Test + public void testCollector() { + JsonArray array = + Stream.of(new JsonPrimitive(1), new JsonArray(), null, new JsonObject()) + .collect(JsonArray.collector()); + assertThat(array).hasSize(4); + assertThat(array.get(0).getAsInt()).isEqualTo(1); + assertThat(array.get(1).isJsonArray()).isTrue(); + assertThat(array.get(2).isJsonNull()).isTrue(); + assertThat(array.get(3).isJsonObject()).isTrue(); + } + + @Test + public void testCollectorParallel() { + JsonArray array = + IntStream.range(0, 20) + .parallel() + .mapToObj(JsonPrimitive::new) + .collect(JsonArray.collector()); + + assertThat(array).hasSize(20); + for (int i = 0; i < array.size(); i++) { + assertThat(array.get(i).getAsInt()).isEqualTo(i); + } + } } diff --git a/pom.xml b/pom.xml index 9b28cce683..f5d2aca093 100644 --- a/pom.xml +++ b/pom.xml @@ -81,6 +81,13 @@ + + org.jspecify + jspecify + 1.0.0 + provided + + junit junit