GSON Double Rounding when adding in HashSet

So I am parsing a VERY large JSON file with the use of GSON. The class I'm parsing it into is structure like this:

What I'm trying to do is round the doubles (in the HashSet, in the Geometry class) up to to 4 decimal points. So as doubles are being added to the HashSet, I want to round them up.

public class Contours {

    public String name = null;
    public String type = null;
    ArrayList<Features> features = null;

    class Features {
        public String type = null;
        public Geometry geometry = null;
        public Properties properties = null;
    }

    class Geometry {
        public String type = null;
        HashSet<double[]> coordinates = null;
    }

    class Properties {
        public String CONTOUR = null;
        public int OBJECTID;
        public String LAYER = null;
        public double ELEVATION;
    }

}

Why I can't do this iteratively after GSON has parsed the file?

The file is VERY large, and has 412,064 lines and is 27.5mb large. So doing that will take very long time.

NOTE: this parsing happens every time this app is run, so speed is necessary.

Thanks

1 answer

  • answered 2018-03-23 02:40 teppic

    You can register a TypeAdapter to modify values as they're read:

    public class GsonDoubleAdapterTest {
        public static void main(String[] args) {
            GsonBuilder builder = new GsonBuilder();
    
            builder.registerTypeAdapter(Double.class, new DoubleAdapter());
    
            Gson gson = builder.create();
            Foo foo = gson.fromJson("{\"baz\": 0.123456}", Foo.class);
            System.out.println(foo);
        }
    }
    
    /**
     * A type adapter that rounds doubles during read.
     */
    class DoubleAdapter extends TypeAdapter<Double> {
        @Override
        public void write(JsonWriter out, Double value) throws IOException {
            out.value(value);
        }
    
        @Override
        public Double read(JsonReader in) throws IOException {
            return new BigDecimal(in.nextDouble()).setScale(4, RoundingMode.HALF_UP).doubleValue();
        }
    }
    
    class Foo {
        private Double baz;
    
        public Double getBaz() {
            return baz;
        }
    
        public void setBaz(Double baz) {
            this.baz = baz;
        }
    
        @Override
        public String toString() {
            return "Foo[baz=" + baz + ']';
        }
    }