【问题标题】:How to load a Map <String, Collection<String>> from a data file?如何从数据文件中加载 Map <String, Collection<String>>?
【发布时间】:2013-11-13 16:19:03
【问题描述】:

java 中是否有一些“本机”格式可以让我编写一个数据文件,然后我可以轻松地将其加载到Map&lt;String, Collection&lt;String&gt;&gt; 中?我宁愿这样做而不必编写任何重要的解析。这将初始化一个应用程序范围的 bean,因此它只在启动时运行一次。

我意识到我可以使用 JSON,然后使用 GSON 之类的东西来加载数据,但这对于看起来很简单的东西来说似乎有点过分了。如果我有闭包,我可以将其创建为属性文件,为我的集合使用特定的分隔符,并在分隔符上解析闭包,但这似乎不太优雅,最重要的是在 Java 中不可用8.

同样,我可以作为一个简单的属性文件加载,然后复制到解析各个属性值的 Map,但似乎又有点“hacky”。​​

我可以使用 XML,然后导入 XML,但这太过分了,我宁愿使用易于理解的简单文本格式。

我不反对使用来自 Apache Commons 或 Guava 等的东西,但还没有发现任何简单的东西。

【问题讨论】:

  • 没有这样的东西。使用 JSON 或 XML 等标准格式。
  • 至于矫枉过正的评论:是的,JSON 对于String -&gt; Collection&lt;String&gt; 来说是“矫枉过正”,但您是否愿意为此使用一种格式,另一种格式用于字符串列表,另一种格式用于列表整数,另一个用于String -&gt; String 的地图等?
  • 为什么 XML 是多余的? Java SE直接支持
  • @GlennLane XML 太过分了,因为它对 XML 文件的编码变得更加复杂。从理论上讲,要正确执行此操作,将意味着创建一个 XSD(或至少是一个 DTD),然后编写 XML。虽然对于这样的事情,它仍然相当简单,但仅仅生成一个 Map> 似乎还是有点矫枉过正。希望有更简单的东西。

标签: java map properties-file


【解决方案1】:

我认为 JSON 是轻量级和简单的,它在内存中的表示是映射或数组的映射,似乎适合这项工作。这会将您的整个文件读取到多图(使用杰克逊):

ObjectMapper mapper = new ObjectMapper();

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

【讨论】:

    【解决方案2】:

    SimpleXML 一个机会。它非常易于使用。

    @Default
    Map<String, Collection<String>> somethingToPersist;
    
    ....
    
    Prersister persister = new Persister();
    File file = new File("/file_path");
    persister.write(somethingToPersist,file)
    

    【讨论】:

    • 以前从未听说过 SimpleXML。感谢您的链接。不过,我对任何 XML 的问题是,对于如此简单的事情来说,它非常冗长。另外,正确地执行它意味着一个 DTD 或一个 XSD 文件,这使得它更加冗长。
    • @Eric B.:XML 可能很冗长,但是对于这个用例(序列化/反序列化),您甚至不需要看它,所以......谁在乎呢?
    【解决方案3】:

    如果您对具有特殊含义的前导选项卡感到满意,我想我会像这样格式化我的文件:

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

    前导制表符表示字符串是(不是)。

    然后是解析器:

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

    用法:

    Map<String, Collection<String>> myMap = MapBuilder.getMap(
            new File("C:/myfile.txt"), Charset.forName("US-ASCII"));
    

    【讨论】:

    • 创意解决方案的全部功劳。也感谢您编写代码的努力!但我认为此时我会坚持使用 JSON 和 Jackson,然后为所有意图和目的编写我自己的解析器。经过一番思考,我意识到我已经生成了 JSON 输出,所以我的应用程序已经与 Jackson 捆绑在一起。我可能会只使用 ObjectMapper 来加载 JSON 格式的文件并完成它。
    猜你喜欢
    • 2018-08-02
    • 1970-01-01
    • 2013-01-14
    • 1970-01-01
    • 2016-12-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多