java 将 HashMap 内容写入文件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/37527177/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 02:35:21  来源:igfitidea点击:

Writing HashMap contents to the file

javahashmapjava-8niojava-stream

提问by Helisia

I have a HashMap<Integer, Integer>. I write its content to the file, so each line of it contains hashmapKey:::hashmapValue. This is how I do it now:

我有一个HashMap<Integer, Integer>. 我将其内容写入文件,因此它的每一行都包含hashmapKey:::hashmapValue. 这就是我现在的做法:

List<String> mLines = new ArrayList<String>();
mHashMap.forEach((key, value) -> mLines.add(key + DATA_SEPARATOR + value));
Files.write(mOutputPath, mLines, StandardCharsets.UTF_8);

I very doubt that I need to copy entire HashMapto the list of strings, I am sure it will give me performance issues when working with big amounts of data. My question is: how can I write HashMapcontents to the file using Java 8 avoiding copying values in another list?

我非常怀疑我是否需要将整个复制HashMap到字符串列表中,我相信在处理大量数据时它会给我带来性能问题。我的问题是:如何HashMap使用 Java 8将内容写入文件以避免复制另一个列表中的值?

回答by Holger

The simplest, non-copying, most “streamish” solution is

最简单、非复制、最“流”的解决方案是

Files.write(mOutputPath, () -> mHashMap.entrySet().stream()
    .<CharSequence>map(e -> e.getKey() + DATA_SEPARATOR + e.getValue())
    .iterator());

While a Stream does not implement Iterable, a lambda expression performing a Stream operation that ends with calling iterator()on the stream, can be. It will fulfill the contract as the lambda expression will, unlike a Stream, produce a new Iteratoron each invocation.

虽然 Stream 未实现Iterable,但执行以调用iterator()流结束的 Stream 操作的 lambda 表达式可以实现。它将履行契约,因为与 Stream 不同,lambda 表达式将Iterator在每次调用时产生一个新的。

Note that I removed the explicit UTF-8character set specifier as java.nio.Fileswill use UTF-8when no charset is specified (unlike the old io classes).

请注意,我删除了在未指定字符集时将使用的显式UTF-8字符集说明符(与旧的 io 类不同)。java.nio.FilesUTF-8

The neat thing about the above solution is that the I/O operation wraps the Stream processing, so inside the Stream, we don't have to deal with checked exceptions. In contrast, the Writer+forEachsolution needs to handle IOExceptions as a BiConsumeris not allowed to throw checked exceptions. As a result, a working solution using forEachwould look like:

上述解决方案的巧妙之处在于 I/O 操作包装了 Stream 处理,因此在 Stream 内部,我们不必处理已检查的异常。相比之下,Writer+forEach解决方案需要处理IOExceptions,因为 aBiConsumer不允许抛出已检查的异常。因此,使用的工作解决方案forEach如下所示:

try(Writer writer = Files.newBufferedWriter(mOutputPath)) {
    mHashMap.forEach((key, value) -> {
        try { writer.write(key + DATA_SEPARATOR + value + System.lineSeparator()); }
        catch (IOException ex) { throw new UncheckedIOException(ex); }
    });
} catch(UncheckedIOException ex) { throw ex.getCause(); }

回答by Robert

You can simply avoid using a List<String>by directly writing out the lines to disk using e.g. a Writer:

您可以List<String>通过使用例如 a 直接将行写出到磁盘来避免使用a Writer

    Writer writer = new BufferedWriter(new OutputStreamWriter(
            new FileOutputStream(new File(mOutputPath)), StandardCharsets.UTF_8));
    mHashMap.forEach((key, value) -> writer.write(key + DATA_SEPARATOR + value + System.lineSeparator()));
    writer.flush();
    writer.close();

回答by Gerald Mücke

You could map the entries of the map to a string and write them to a FileChannel. The additional methods simply do the exception handling so the stream operations become more readable.

您可以将映射的条目映射到字符串并将它们写入FileChannel. 附加方法只是简单地进行异常处理,因此流操作变得更具可读性。

final Charset charset =  Charset.forName("UTF-8");
try(FileChannel fc = FileChannel.open(mOutputPath, StandardOpenOption.WRITE, StandardOpenOption.CREATE_NEW)) {
    mHashMap.entrySet().stream().map(e -> e.getKey() + ":::" + e.getValue() + "\n")
            .map(s -> encode(charset, s))
            .forEach(bb -> write(fc, bb));
}

void write(FileChannel fc, ByteBuffer bb){
    try {
        fc.write(bb);
    } catch (IOException e) {
        throw new RuntimeException(e);
    }
}

ByteBuffer encode( Charset charset, String string){
    try {
        return charset.newEncoder().encode(CharBuffer.wrap(string));
    } catch (CharacterCodingException e) {
        throw new RuntimeException(e);
    }
}

回答by uniknow

HashMapimplements Serializableso you should be able to use standard serialization to write hashmap to file.

HashMap实现,Serializable因此您应该能够使用标准序列化将 hashmap 写入文件。

Example:

例子:

HashMap<Integer, String> hmap = new HashMap<Integer, String>();

//Adding elements to HashMap

try {
    FileOutputStream fos =
            new FileOutputStream("example.ser");
    ObjectOutputStream oos = new ObjectOutputStream(fos);
    oos.writeObject(hmap);
    oos.close();
    fos.close();
}catch(IOException ioe) {
    ioe.printStackTrace();
}