Question

Is there some "native" format in java that will allow me to write up a data file that I can then easily load into a Map<String, Collection<String>>? I would rather do this without having to code any significant parsing. This would be to initialize an application-scoped bean, so it is only run once at startup.

I realize I can use JSON and then use something like GSON to load the data, but that seems like overkill for something that would appear to be simple. If I had closures, I could potentially create it as a property file, use a specific separator for my collection, and have the closure parse on the separator, but that doesn't seem very elegant, and most importantly isn't available in Java 8.

Similarly, I can load as a simple properties file and then copy over to a Map parsing the individual property values, but again seems a little "hacky".

I could use XML and then import the XML, but that is way overkill and would rather have a simple text format that is easily understood.

I am not against using something from Apache Commons or Guava, etc, but haven't found anything straightforward yet.

Was it helpful?

Solution

My opinion is that JSON is lightweight and simple, it's in-memory representation is a map of maps or arrays, seems to suit the job. This would read your entire file to a multimap (uses Jackson):

ObjectMapper mapper = new ObjectMapper();

Map<String, List<String>> map = mapper.readValue(inputStream,
     new TypeReference<Map<String, Object>>() {});

OTHER TIPS

Give SimpleXML a shot. it's ridiculously easy to use.

@Default
Map<String, Collection<String>> somethingToPersist;

....

Prersister persister = new Persister();
File file = new File("/file_path");
persister.write(somethingToPersist,file)

If you're OK with a leading tab having special meaning, I guess I would format my file like:

key1
    value1-a
    value1-b
key2
    value2-a
key3
    value3-a
    value3-b
    value3-c

Where a leading tab means the string is a value (not a key).

Then the parser:

public class MapBuilder
{
    private final Map<String, Collection<String>> map;
    private Collection<String> col;

    public MapBuilder()
    {
        map = new LinkedHashMap<String, Collection<String>>();
    }

    public Map<String, Collection<String>> getMap()
    {
        return map;
    }

    public void addLine(String line)
    {
        if (line.length() > 0)
        {
            if (line.charAt(0) == '\t')
            {
                if (col == null)
                {
                    throw new IllegalArgumentException(
                            "No key specified");
                }
                col.add(line.substring(1));
            }
            else
            {
                col = new ArrayList<String>();
                map.put(line, col);
            }
        }
    }

    public static Map<String, Collection<String>> getMap(File file, 
            Charset charset) throws IOException
    {
        MapBuilder mb = new MapBuilder();
        BufferedReader br = new BufferedReader(new InputStreamReader(
                new FileInputStream(file), charset));
        try
        {
            String line;
            while ((line = br.readLine()) != null)
            {
                mb.addLine(line);
            }
            return mb.getMap();
        }
        finally
        {
            try
            {
                br.close();
            }
            catch (Throwable t)
            {
                t.printStackTrace();
            }
        }
    }
}

Usage:

Map<String, Collection<String>> myMap = MapBuilder.getMap(
        new File("C:/myfile.txt"), Charset.forName("US-ASCII"));
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top