Skip to content

Chapter Intro Handling Value Sequences

Tatu Saloranta edited this page Sep 7, 2016 · 2 revisions

Jackson Manual: Introduction - Reading and Writing Value Sequences

Another type of commonly encountered data structure is that of a sequence of values. This includes cases where some properties have multiple values as an array (such as phoneNumber property of the User class defined earlier), as well as files that consists of longer sequences of values.

For example, we could have a dataset consisting of just 3-dimensional coordinates, logically represented as simple value type:

public class Point {
  int x, y, z;
}

or as JSON:

{ "x":1, "y":3,"z":-5 }

A natural representation of a data set consisting of a large number of such coordinates could look something like:

{ "x":1, "y":3,"z":-5 }
{ "x":4, "y":-5,"z":0 }
{ "x":-4, "y":2,"z":1 }
{ "x":0, "y":1,"z":6 }

where each JSON Object value is on its own row (*).

(*) note that Jackson only requires a white-space separator, not necessarily linefeed. But many other frameworks assume or require linefeed so it has become the de-facto standard separator.

Not standard, but widely used

One thing worth noting is that format suggested above -- one value per line, or more generally, values separated by whitespace but no separator marker -- is not strictly-speaking valid JSON, and specifically does not a valid JSON value. But it can be viewed as a very simple framing format where the super-structure consists of individual JSON Values (in above case, JSON Objects) separated by white space.

Jackson supports processing of such value sequences, as do many other JSON libraries and data processing frameworks, especially ones used for processing so-called "Big Data".

Reading value sequences

Reading value sequences is not very different from reading individual values:

MappingIterator<Point> iter = mapper.readerFor(Point.class)
  .readValues(new File("points.json"));
while (it.hasMoreValues()) {
   Point p = it.nextValue();
}
it.close();

// or for convenience, just read 'em all:
List<Point> points = mapper.readerFor(Point.class)
  .readValues(new File("points.json"))
  .readAll();

and you can choose between just reading all values in, or processing them one-by-one.

Writing value sequences

Similarly, you can write such data sets incrementally as well:

SequenceWriter w = mapper.writerFor(Point.class)
  .writeValues(new File("results.json"));
for (Point p : points) {
  w.write(p);
}
w.close();

Note on sequences with other data formats

While we have not yet covered data formats beyond JSON (*), it is worth noting that:

  1. Not all data formats (and modules to support them) support concept of value sequences (for example, XML does not)
  2. Representation of value sequences is format-dependant so that, for example, linefeed-separation is only valid for some formats like JSON and CSV, and other formats may require or support different methods of element separation

(*) we will in due time, see Chapter X