-1

i have below model classes for example

class A{}
class B{}

Main or calling class

public static void main(String[] args) throws IOException{
  String aJson = "/tmp/a.json";
  List<A> aList = readAJsonAsList(aJson);
  String bJson = "/tmp/b.json";
  List<B> bList = readBJsonAsList(bJson);
}

Now I am reading json files analogous to models A and B using jackson.

// method for A
    private static List<A> readAJsonAsList(String jsonAFile) throws IOException {
        ObjectMapper omA = new ObjectMapper();
        List<A> aList = omA.readValue(new File(jsonAFile), new TypeReference<ArrayList<A>>() {
        });
        return aList;
    }
    
// method for B
    private static List<B> readBJsonAsList(String jsonBFile) throws IOException {
        ObjectMapper omB = new ObjectMapper();
        List<B> bList = omB.readValue(new File(jsonBFile), new TypeReference<ArrayList<B>>() {
        });
        return bList;
    }

how can I make one generic java method from above two methods?

Note: I have tried below but does not work

private static <T> List<T> readJsonAsList(String jsonFile) throws IOException {
    ObjectMapper objectMapper = new ObjectMapper();
    List<T> list = objectMapper.readValue(new File(jsonFile), new TypeReference<ArrayList<T>>() {
    });
    return list;
}
axnet
  • 5,146
  • 3
  • 25
  • 45

1 Answers1

0

You need to provide the element type as method parameter and use TypeFactory, more precisely TypeFactory.constructCollectionType(collectionClass, elementClass) to build the JavaType dynamically at runtime.

Additionally i would suggest to use InputStream as the parameter, it's more generic and you can use the method with basically anything (file streams, you can convert text to streams, other streams).

public class Test {

  public static void main(String[] args) {
    try (FileInputStream stream = new FileInputStream("path-to-file")) {
      List<A> aList = readAsList(stream, A.class);
      System.out.println(aList);
    } catch (IOException exc) {
      exc.printStackTrace();
    }
  }

  private static <T> List<T> readAsList(InputStream inputStream, Class<T> elementType) throws IOException {
    ObjectMapper mapper = new ObjectMapper();
    TypeFactory factory = TypeFactory.defaultInstance();
    return mapper.readValue(inputStream, factory.constructCollectionType(List.class, elementType));
  }

  private static class A {
  }

  private static class B {
  }
}
Chaosfire
  • 4,818
  • 4
  • 8
  • 23