1

Using Java 8. I want to make a generic function that I can use for mapping the contents of a JSONArray object to a certain class. The inputs to this function will be a JSONArray and a class object that has a constructor that will turn the individual JSONObjects inside the JSONArray into the appropriate POJO.

I want something like this:

public static List<T> getObjectsFromJSONArray(Class T, JSONArray input) {
    return IntStream.range(0, input.length())
            .mapToObj(index -> (JSONObject)input.get(index))
            .collect(Collectors.toList())
            .forEach(jsonObj -> new T(jsonObj));
}

This doesn't compile. Perhaps because I am new to Java and am not accustomed to it, I want to make this a generic function.

One possible alternate solution is to make a class U<T>, that extends List and acts for all intents and purposes as a List<T>. The constructor for U would then take the whole JSONArray then my code works with the type specified. I've seen that implementation in action before, but it seems cumbersome to me. Let me know if a new class U is indeed the 'best practices' way to do this in Java.

kingledion
  • 2,263
  • 3
  • 25
  • 39
  • 3
    if possible you could use a library to help you with that, gson for example, https://stackoverflow.com/questions/19133944/how-to-convert-jsonarray-to-list-with-gson/19134069 here they solve a similar problem – Edwin Oct 26 '18 at 20:23
  • 6
    Read about type erasure. "new T" is simply not possible. And yes: use a framework like Jackson or gson instead of reinventing the wheel. – GhostCat Oct 26 '18 at 20:26
  • Possible duplicate of [How to convert JSONArray to List with Gson?](https://stackoverflow.com/questions/19133944/how-to-convert-jsonarray-to-list-with-gson) – Dan W Oct 26 '18 at 21:09
  • @GhostCat Not going to lie, I spent about 4 working days failing to get Jackson to work. That library suffers from a steep learning curve and a dearth of useful tutorials online, that is for sure. Took me about 4 hours to implement a web API client from scratch using just java builtins and org.json (would have been like 1 hour in python, probably). I hold the opinion that there is a real need for a bare bones, trivial to learn JSON/XML API client package in Java. I wish I had never wasted my time on Jackson. – kingledion Oct 27 '18 at 00:09
  • 1
    @kingledion I use Jackson (because I use spring boot, which uses Jackson by default), and I’ve never had a problem with this kind of thing. What exactly did you try? BTW I highly recommend spring boot, as among many other awesome features, it serialises/deserialises from HTTP calls automatically, as in with zero json-related code: You just declare a method that returns/accepts (in your case) a list of things and hey presto you’re done. – Bohemian Oct 27 '18 at 00:34
  • @Bohemian [This](https://stackoverflow.com/questions/52975383/reading-json-to-java-object-with-jersey-2-27-and-jackson) is the closest I got to getting Jackson to work. I could not for the life of me get it to deserialize JSON to POJO. – kingledion Oct 27 '18 at 00:40
  • 1
    @kingledion it’s trivial to deserialise from a String to a `List` using jackson; would that work for you? Do you actually *need* to work with JSONObjects? – Bohemian Oct 27 '18 at 03:24
  • 1
    Besides the impossibility to do `new T(...)`, what is `.forEach(jsonObj -> new T(jsonObj))` supposed to do? – Holger Oct 27 '18 at 12:06

1 Answers1

2

How about something like

   public static <T> List<T> getObjectsFromJSONArray(Function<JSONObject, T> factory, JSONArray input) {
    return IntStream.range(0, input.length())
      .mapToObj(index -> factory.apply((JSONObject)input.get(index)))
      .collect(Collectors.toList());
  }

and then you use it like

getObjectsFromJSONArray(YourObject::new, jsonarray)
taygetos
  • 3,005
  • 2
  • 21
  • 29
  • This is not fully what the op wants, in the example of the OP, he loops through the every entry of the json array, and you just try to cast it – Ferrybig Oct 26 '18 at 21:54
  • This is excellent thank you. I'm not familiar with the `` notation before the return value? What is that called? Where can I learn about that? – kingledion Oct 27 '18 at 00:20
  • 1
    @kingledion it's a type parameter. Since you have tagged you question with `[generics]` yourself, you should have heard about it. – Holger Oct 27 '18 at 12:09
  • 1
    @kingledion you can read up on the basics of generics e.g. here: https://www.baeldung.com/java-generics – taygetos Oct 27 '18 at 17:48