简体   繁体   English

将HashMap内容写入文件

[英]Writing HashMap contents to the file

I have a HashMap<Integer, Integer> . 我有一个HashMap<Integer, Integer> I write its content to the file, so each line of it contains hashmapKey:::hashmapValue . 我将其内容写入文件,因此它的每一行都包含hashmapKey:::hashmapValue This is how I do it now: 这是我现在这样做的方式:

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. 我非常怀疑我需要将整个HashMap复制到字符串列表中,我相信在处理大量数据时它会给我带来性能问题。 My question is: how can I write HashMap contents to the file using Java 8 avoiding copying values in another list? 我的问题是:如何使用Java 8将HashMap内容写入文件,避免在另一个列表中复制值?

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. 虽然Stream没有实现Iterable ,但是执行Stream操作的lambda表达式可以在流上调用iterator()结束。 It will fulfill the contract as the lambda expression will, unlike a Stream, produce a new Iterator on each invocation. 它将履行合同,因为lambda表达式将与Stream不同,在每次调用时生成一个新的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字符集说明符,因为java.nio.Files在没有指定charset时将使用UTF-8 (与旧的io类不同)。

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. 上述解决方案的优点在于I / O操作包装了Stream处理,因此在Stream内部,我们不必处理已检查的异常。 In contrast, the Writer + forEach solution needs to handle IOException s as a BiConsumer is not allowed to throw checked exceptions. 相反, Writer + forEach解决方案需要处理IOException因为不允许BiConsumer抛出已检查的异常。 As a result, a working solution using forEach would look like: 因此,使用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(); }

You can simply avoid using a List<String> by directly writing out the lines to disk using eg a Writer : 您可以通过使用例如Writer直接将行写入磁盘来避免使用List<String>

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

You could map the entries of the map to a string and write them to a FileChannel . 您可以将地图的条目映射到字符串并将其写入FileChannel The additional methods simply do the exception handling so the stream operations become more readable. 其他方法只是执行异常处理,因此流操作变得更易读。

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

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM