// In this demo, we use Google's FOSS JSON library "Gson" to
// easily convert a complex Map to JSON and back again.
// This code originally downloaded from
//  <https://github.com/google/gson/blob/master/extras/src/main/
//     java/com/google/gson/extras/examples/rawcollections/
//     RawCollectionsExample.java>
// Modified 3/2017 by Wayne Pollock, Tampa Florida USA

// Download gson.jar (and optionally the API docs, also in a jar) from
//  <https://search.maven.org/#search%7Cga%7C1%7Cg%3A%22com.google.code.gson%22>
// Make sure that jar file is on your CLASSPATH.

import java.lang.reflect.Type;
import java.util.*;
import com.google.gson.*;
import com.google.gson.reflect.TypeToken;

public class GsonDemo {
  static class Event {  // Trivial class to show off Gson.
    private int id;
    private String detail;
    private Event(int id, String detail) {
      this.id = id;
      this.detail = detail;
    public String toString() {
      return String.format( "(id=%d, detail=%s)", id, detail );

  public static void main(String[] args) {
    // Create a gson object:
    //Gson gson = new Gson();  // Creates "compact" JSON text, no nulls.
    Gson gson = new GsonBuilder().setPrettyPrinting().serializeNulls().create();

    Map<String, Set<Event>> map = new HashMap<>();

    Set<Event> set = new HashSet<>();
    set.add( new Event(1, "Birthday") );
    set.add( new Event(2, "Work Anniversary") );
    map.put( "Events1", set );

    map.put( "Events2", null );  // Just because we can!

    set = new HashSet<>();  // Make another set
    set.add( new Event(3, "Vacation") );
    set.add( new Event(4, "Holiday") );
    set.add( new Event(5, "In-service Day") );
    map.put( "Events3", set );

    // Convert Java collection to JSON:
    String json = gson.toJson( map );
    System.out.println( "\nUsing Gson.toJson():\n" + json );

    // Convert JSON to Java collection:

    // First, create a Java Type object to represent the class of the object,
    // in this case a Map<String, Set<Event>>.  This is required since JSON
    // doesn't include any class information; there's no automatic way
    // to convert JSON back to complex objects without telling the library
    // the exact type to use.  (Going from objects to JSON is no problem.)
    // This is done by creating an anonymous inner class that extends
    // Gson's "TypeToken" class, then using the getType method:
    Type stringToSetOfEventMap =
        new TypeToken<Map<String, Set<Event>>>(){}.getType();

    Map<String,Set<Event>> map2 = gson.fromJson(json, stringToSetOfEventMap);
    System.out.println( "\n\nUsing Gson.fromJson():\n" + map2.toString() );