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
Writing HashMap contents to the file
提问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 HashMap
to 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 HashMap
contents 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 Iterator
on each invocation.
虽然 Stream 未实现Iterable
,但执行以调用iterator()
流结束的 Stream 操作的 lambda 表达式可以实现。它将履行契约,因为与 Stream 不同,lambda 表达式将Iterator
在每次调用时产生一个新的。
Note that I removed the explicit UTF-8
character set specifier as java.nio.Files
will use UTF-8
when no charset is specified (unlike the old io classes).
请注意,我删除了在未指定字符集时将使用的显式UTF-8
字符集说明符(与旧的 io 类不同)。java.nio.Files
UTF-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
+forEach
solution needs to handle IOException
s as a BiConsumer
is not allowed to throw checked exceptions. As a result, a working solution using forEach
would look like:
上述解决方案的巧妙之处在于 I/O 操作包装了 Stream 处理,因此在 Stream 内部,我们不必处理已检查的异常。相比之下,Writer
+forEach
解决方案需要处理IOException
s,因为 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
HashMap
implements Serializable
so 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();
}