Pregunta

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.

¿Fue útil?

Solución

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>>() {});

Otros consejos

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"));
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top