Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Writing HashMap contents to the file

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:

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?

like image 848
Helisia Avatar asked May 30 '16 13:05

Helisia


People also ask

How to write a hashmap to a plain text file?

De-Serialization: It is a process of reading the Object and its properties from a file along with the Object’s content. If we want to write a HashMap object to a plain text file, we need a simple and understandable code to write on the HashMap and then insert the Map into the Text File.

What is the output of HashMap in Java?

The HashMap class in Java implements the Serializable interface so that its objects can be written or serialized to a file using the ObjectOutputStream. However, the output file it produces is not in the human-readable format and may contain junk characters.

How to write a hashmap to a location in SQL Server?

The hashmap.ser serialised file can be Stored to any Location with describing it’s Location Like Below So we need the Location to write the HashMap in it. Using the file object we will write the HashMap input using the function BufferedWriter(File_Path)

How to create a hashmap from Excel data?

Create the workbook and get the sheet for that Excel. Declare the HashMap for storing the data from Excel. Iterate through the Rows to get the Key and value data. Add the data into the HashMap using the put method. For displaying HashMap iterate through the map and print the output.


3 Answers

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.

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).

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 IOExceptions as a BiConsumer is not allowed to throw checked exceptions. As a result, a working solution using forEach would look like:

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(); }
like image 191
Holger Avatar answered Sep 18 '22 21:09

Holger


You can simply avoid using a List<String> by directly writing out the lines to disk using e.g. 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();
like image 32
Robert Avatar answered Sep 21 '22 21:09

Robert


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.

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);
    }
}
like image 35
Gerald Mücke Avatar answered Sep 20 '22 21:09

Gerald Mücke