我有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);
我非常怀疑我需要将整个HashMap
复制到字符串列表中,我相信在处理大量数据时它会给我带来性能问题。我的问题是:如何使用Java 8将HashMap
内容写入文件,避免在另一个列表中复制值?
答案 0 :(得分:14)
最简单,非复制,最“流畅”的解决方案是
Files.write(mOutputPath, () -> mHashMap.entrySet().stream()
.<CharSequence>map(e -> e.getKey() + DATA_SEPARATOR + e.getValue())
.iterator());
虽然Stream没有实现Iterable
,但是执行Stream操作的lambda表达式可以在流上调用iterator()
结束。它将履行契约,因为与Stream不同,lambda表达式将在每次调用时生成一个新的Iterator
。
请注意,我删除了显式UTF-8
字符集说明符,因为java.nio.Files
在没有指定字符集时会使用UTF-8
(与旧的io类不同)。
上述解决方案的巧妙之处在于I / O操作包装了Stream处理,因此在Stream中,我们不必处理已检查的异常。相反,Writer
+ forEach
解决方案需要处理IOException
,因为BiConsumer
不允许抛出已检查的异常。因此,使用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(); }
答案 1 :(得分:3)
您可以通过使用以下方法直接将行写入磁盘来避免使用List<String>
。 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();
答案 2 :(得分:1)
您可以将地图的条目映射到字符串并将其写入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);
}
}
答案 3 :(得分:-1)
HashMap
实现Serializable
,因此您应该能够使用标准序列化将hashmap写入文件。
示例:的
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();
}