You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The current JSONArray#toList() converts the array to a list of Object. This makes things a little tough to work with.
When, for example, you have a list of typically JSON Objects or Strings, you have to do something like this:
jarr.toList().stream().map(Object::toString).toList(); // List of stringjarr.toList().stream().map(o -> (JSONObject) o).toList(); // List of JSONObject
I wrote a function that implments this, but I'm not too Java experty to know if it's ideal:
/** * Converts a JSONArray to a list of {@code <T>}. * * @param array The JSONArray * @param cast The class to cast to * @param <T> The type to cast to * @return A list of {@code <T>} */publicstatic <T> List<T> toList(JSONArrayarray, Class<T> cast) {
List<T> results = newArrayList<>(array.length());
for (Objectelement : array) {
if (element == null || JSONObject.NULL.equals(element)) {
results.add(null);
} else {
results.add(cast.cast(element));
}
}
returnresults;
}
It's a little messy but it essentially casts each item in the array to the specific object. This is of course missing any exception handling since ClassCastException is likely.
Am I going about my suggestion all wrong? Is there already a way to do this? Please let me know 😄
I think your function is the right idea, but not quite there. I'd implement this similar to what you have, but more like this:
/** * Converts a JSONArray to a list of {@code <T>}. * * @param array The JSONArray * @param cast The class to cast to * @param ignoreInvalid when true, items that can't be cast are not added to the result array as null. If false, items that can't be cast will be inserted as null. Values that are null before casting will be kept as null in the result array. * @param <T> The type to cast to * @return A list of {@code <T>} */publicstatic <T> List<T> toList(JSONArrayarray, Class<T> cast, booleanignoreInvalid) {
List<T> results;
if(ignoreInvalid) results = newArrayList<>();
elseresults = newArrayList<>(array.length());
for (Objectelement : array) {
if (JSONObject.NULL.equals(element)) {
results.add(null);
} elseif(cast.isAssignableFrom(element.getClass()) {
results.add(cast.cast(element));
} elseif(!ignoreInvalid) {
results.add(null);
}
}
returnresults;
}
using isAssignableFrom prevents any need for exception handling, and trimming out unwanted items from the result array that don't cast can save time on processing the result in downstream processors.
personally, I wouldn't bother with toList at all in your use-case though. as in #672, I would just use the spliterator to get a stream and continue to use the Map option like you do:
java.util.StreamSupport(jarr.spliterator(), false)
.filter(Objects::nonNull)
.filter(i-> JSONObject.class.isAssignableFrom(i.getClass())
.map(i-> (JSONObject)i)
// process
;
Using toList defeats the purpose of using a stream in the first place which is to prevent creation of extra object (in this case an entire array).
@Chew No objections if you would like to submit a pull request. Please make sure the code either handles exceptions or has a language supported workaround. Keep in mind the project's Java version requirement: What version of Java does this project require?
Activity
johnjaylward commentedon Mar 21, 2022
I think your function is the right idea, but not quite there. I'd implement this similar to what you have, but more like this:
using
isAssignableFromprevents any need for exception handling, and trimming out unwanted items from the result array that don't cast can save time on processing the result in downstream processors.johnjaylward commentedon Mar 21, 2022
personally, I wouldn't bother with toList at all in your use-case though. as in #672, I would just use the spliterator to get a stream and continue to use the Map option like you do:
Using
toListdefeats the purpose of using a stream in the first place which is to prevent creation of extra object (in this case an entire array).johnjaylward commentedon Mar 21, 2022
if you want to make that as a helper method, it would look something like this:
stleary commentedon Mar 22, 2022
@Chew No objections if you would like to submit a pull request. Please make sure the code either handles exceptions or has a language supported workaround. Keep in mind the project's Java version requirement: What version of Java does this project require?
johnjaylward commentedon Sep 5, 2023
@stleary , looks like the wiki needs a quick update to note the move to Java8 : https://github.com/stleary/JSON-java/wiki/FAQ#what-version-of-java-does-this-project-require
stleary commentedon Sep 5, 2023
@johnjaylward Should be updated now, thanks for catching this.
stleary commentedon Sep 30, 2023
Closing this issue. Please post here if you disagree.