1

In Java, is there a nice way of serializing a collection of objects as a single JSON object of parallel arrays?

For example, given a Collection of type Person

class Person {
  String firstName;
  String lastName;
  int age;
}

I would want to produce the following JSON:

{
  "firstName": ["Allison", "Stanley", "Adrian"],
  "lastName": ["Smith", "Williams", "Davis"],
  "age": [23, 17, 42]
}

I'd prefer to use jackson if possible, but all suggestions are welcome.

Erik Goepfert
  • 157
  • 2
  • 8

2 Answers2

3

You really shouldn't be doing that. Parallel arrays are an anti-pattern.

If you insist (people will hate you), create a class for it and convert the data before generating JSON.

class PersonList {
  List<String> firstName;
  List<String> lastName;
  List<Integer> age;

  PersonList(List<Person> persons) {
    for (Person p : persons)
      add(p);
  }

  void add(Person p) {
    firstName.add(p.getFirstName());
    lastName.add(p.getLastName());
    age.add(p.getAge());
  }
}
List<Person> persons = ...

ObjectMapper mapper = new ObjectMapper();
mapper.writeValue(..., new PersonList(persons));
Andreas
  • 154,647
  • 11
  • 152
  • 247
0

I was hoping to find an option that didn't require a new PersonList class. One that could take advantage of all of the introspection logic built into Jackson and identify the properties of Person to generate the JSON lists for me.

I'm not seeing anything like that, so extending from the suggestion by Andreas, I'm using Guava's Lists.transform() to create the property lists as views of the original, without duplicating the data.

class PersonList {
  List<String> firstName;
  List<String> lastName;
  List<Integer> age;

  public PersonList(List<Person> people) {
    this.firstName = Lists.transform(people, Person::getFirstName);
    this.lastName = Lists.transform(people, Person::getLastName);
    this.age = Lists.transform(people, Person::getAge);
  }

  // getters...
}
Erik Goepfert
  • 157
  • 2
  • 8