skip to Main Content

I have a chunk of code like this:

public class Plays {
    private Hamlet hamlet;
    private AsLike aslike;
    private Othello othello;

    public Plays() {
    
    }

    //getters & setters
}

I know it would be better to do a class "Play.java" instead of "Plays.java", and then store the different instances into a list, but I have to parse a json file and the json is written as nested objects:

{
    "hamlet": {
         "name": "Hamlet",
         "type": "tragedy"
     },
     "aslike": {
         "name": "As You Like It",
         "type": "comedy"
     },
     "othello": {
         "name": "Othello",
         "type": "tragedy"
     }
}

First rule: this json file cannot be modified, as bad as it looks. The issue is that my json parser of course wouldn’t parse correctly if the java structure was different than the json one, so I don’t see how could I change that. But that’s not the real problem.

The problem now is I have to compare a String value to the name itself of an attribute (hamlet, aslike or othello) of the Plays class. For example, I want the program to verify if the word "hamlet" is the same as the attribute’s name (hamlet) of the Plays class. Is it even possible? I know the problem lies in the code structure, but as I said I don’t really know how to change that without messing up the parsing (as long as I know, a json object must correspond to an object in java, a json list a list in java etc…).

2

Answers


  1. Chosen as BEST ANSWER

    Ok, didn't really find a solution to my "comparing name with an attibute's name" problem, but i found a workaround. Thanks to @tgdavies for the cue, even if unintentional.

    My solution was using nested HashMaps in a form like this:

    HashMap<Object, HashMap<String, String>>
    

    to parse the json code. This way it doesn't mess the parsing itself and I'm also assigning each object to his properties expressed as strings, which allows me to access them easily and correctly.


  2. Unless you really do want a different implementation for each named play, rather than a simple POJO which holds name and type, do it like this:

    import com.fasterxml.jackson.core.type.TypeReference;
    import com.fasterxml.jackson.databind.ObjectMapper;
    
    import java.io.IOException;
    import java.util.Map;
    
    public class Test2 {
        public static void main(String[] args) throws IOException {
            ObjectMapper mapper = new ObjectMapper();
            String json = "{n" +
                    "    "hamlet": {n" +
                    "         "name": "Hamlet",n" +
                    "         "type": "tragedy"n" +
                    "     },n" +
                    "     "aslike": {n" +
                    "         "name": "As You Like It",n" +
                    "         "type": "comedy"n" +
                    "     },n" +
                    "     "othello": {n" +
                    "         "name": "Othello",n" +
                    "         "type": "tragedy"n" +
                    "     }n" +
                    "}";
            Map<String,Play> plays = mapper.createParser(json)
                .readValueAs(new TypeReference<Map<String,Play>>() {});
        }
    }
    
    class Play {
        public String name;
        public String type;
    }
    

    We have told ObjectMapper that we want the data as a Map<String,Play>, so it will use the attribute names in the top level JSON object (i.e."hamlet", "aslike" and so on) as keys in the Map, and use the structure of the Play class to parse the values of those attributes.

    Once you have that data structure you can iterate over the Map entries to verify that the key of the entry matches the name field of the value.

    How you’ll verify that "aslike" matches "As You Like It", I don’t know.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search