JavaxJson { @SuppressWarnings("WeakerAccess") public static <R> List<R> parseFromArray(final @NotNull JsonArray jsonArray, final @NotNull Fun.ThrowingFunction<String, R> parser, final @Nullable BiConsumer<String, Exception> errorConsumer) { return jsonArray.stream() .map(JSON_VALUE_STRING) .flatMap(Fun.composeTry1(Stream::of, Stream::empty, parser, errorConsumer)) .collect(Collectors.toList()); } private  JavaxJson(); static boolean nonEmptyValue(final @Nullable JsonValue value); static boolean nonDefaultValue(final @Nullable JsonValue value, final @NotNull JsonValue defaultValue); static JsonValue wrap(final Object object); @SuppressWarnings("WeakerAccess") static Object unwrap(final JsonValue jsonValue); @SuppressWarnings("WeakerAccess") static Map<String, Object> unwrapObject(final JsonObject jsonObject); @SuppressWarnings("WeakerAccess") static List<Object> unwrapArray(final JsonArray jsonArray); static @NotNull JsonObject shallowMergeObjects(final @Nullable JsonObject base,
                                                          final @Nullable JsonObject overlay); static Value val(Object value); static Obj obj(final Key... keys); static Obj obj(final JsonObject jsonObject); static Obj obj(final Map<?, ?> map); static Key key(final String key, final Object value); static KeyCursor key(final String key); static Arr arr(Object... values); @SuppressWarnings("WeakerAccess") static Optional<JsonObject> optObject(final JsonObject json, final String key); @SuppressWarnings("WeakerAccess") static JsonObject objectOrEmpty(final JsonObject json, final String key); @SuppressWarnings("WeakerAccess") static Optional<JsonArray> optArray(final JsonObject json, final String key); static JsonArray arrayOrEmpty(final JsonObject json, final String key); static List<String> mapArrayOfStrings(final JsonArray jsonArray); static List<R> mapArrayOfStrings(final JsonArray jsonArray,
                                                final Function<String, R> mapFunction); static List<R> mapArrayOfStrings(final JsonArray jsonArray,
                                                final Function<String, R> mapFunction,
                                                final boolean discardNulls); static List<R> mapArrayOfObjects(final JsonArray jsonArray,
                                                final Function<JsonObject, R> mapFunction); static List<R> mapArrayOfObjects(final JsonArray jsonArray,
                                                final Function<JsonObject, R> mapFunction,
                                                final boolean discardNulls); static List<R> mapObjectValues(final JsonObject jsonObject,
                                              final BiFunction<String, JsonObject, R> mapBiFunction,
                                              final boolean discardNulls); @SuppressWarnings("WeakerAccess") static List<R> parseFromArray(final @NotNull JsonArray jsonArray,
                                             final @NotNull Fun.ThrowingFunction<String, R> parser,
                                             final @Nullable BiConsumer<String, Exception> errorConsumer); static boolean hasNonNull(final @NotNull JsonObject json, final String key); @SuppressWarnings("WeakerAccess")
    static final Function<JsonValue, String> JSON_VALUE_STRING; }
@Test public void testParseFromArray() { final JsonArray input = arr().val("foo1:bar1").val("foo2:bar2").val("notvalid").val("foo3:bar3").get(); final List<Map.Entry<String, String>> expected = Arrays.asList( toEntry("foo1", "bar1"), toEntry("foo2", "bar2"), toEntry("foo3", "bar3") ); final CompletableFuture<Map.Entry<String, Exception>> errorLatch = new CompletableFuture<>(); final List<Map.Entry<String, String>> parsed = JavaxJson.parseFromArray(input, value -> { if (value.contains(":")) { final String[] parts = value.split(":", 2); return toEntry(parts[0], parts[1]); } else { throw new IllegalArgumentException("missing colon"); } }, (value, error) -> errorLatch.complete(toEntry(value, error))); assertEquals("parse function should work", expected, parsed); assertTrue("error latch is done", errorLatch.isDone()); final Map.Entry<String, Exception> fromLatch = errorLatch.getNow(toEntry("", new Exception(""))); assertEquals("error latch key is", "notvalid", fromLatch.getKey()); assertEquals("error latch error message is", "missing colon", fromLatch.getValue().getMessage()); }