简体   繁体   中英

Java I/O and HashMap

I have a text file that looks like following:

A
Apple
B
Bat
C
Cat

......

I need to read this text file and save it in a HashMap where an odd line is a key and the following even line is the value. For example, (A, Apple). I have tried with the following code, it doesn't work. Can someone give me a hint or advice on how I can do it?

     private HashMap<String, String> newHashMap = new HashMap<String, String>();

    Charset charset = Charset.forName("US-ASCII");

    Path path = Paths.get("file_location");
    try (BufferedReader reader = Files.newBufferedReader(path, charset)) {
        int lineCount = 0;
        String key;
        String value;

        String line = reader.readLine();
        while(line != null) {


            line = reader.readLine();

            if (lineCount % 2 == 1)
            {
            key = reader.readLine() ;

            }
            else if( lines % 2 == 0)
            {
            value = reader.readLine();

            }

            lineCount++;
           newHashMap.put(key, value);
        }

As others have said, the if statements and lineCount variable are redundant here. The first time you call readLine is causing an issue as well because you're essentially skipping the first line in the textfile. What you should do instead is call (line = r.readLine()) != null) inside your while loop so that you have access to the read line within the loop while also being able to avoid reading after the end of the file. Also, this line inside the while loop line = reader.readLine(); is unnecessary as well. It caused you to read an extra line per iteration, and skipping it since it was never used. Besides reading in a line inside the while loop header, just read another line inside the while loop and assign each line to the right variables ( key , value ) like so,

while((line = reader.readLine()) != null) {
       key = line;
       value = reader.readLine();
       newHashMap.put(key, value);
}

and right outside the while loop, change String line = reader.readLine(); to

String line = "";

You already have variables for key and value so use then intiially

    String key = reader.readLine();
    String value = reader.readLine();

    while(key != null && value != null) {
       newHashMap.put(key, value);
       key = reader.readLine();
       value = reader.readLine();
    }

The main problem with your code seems to be that you are not aware of the fact that calling bufferedReader.readLine() method 'n' times would read 'n' lines (if they are available). See here for more details. So what your code should look like is this :-

String key = reader.readLine();

while(key!=null){
String value = reader.readLine();
newHashMap.put(key, value);
key = reader.readLine();
}

Provided your input file has no trailing keys, the above code should work

Your approach is sound, just move the newHashMap.put(key, value); inside the else if block. You want to add to the map only every second line, after you have read the value.

A tweak would be to do

else if( lines % 2 == 0) {
        value = reader.readLine();
        newHashMap.put(key, value); // update when you've pair of values(key + value)
}

and none the less, the line

String line = reader.readLine();

makes you skip the first line of input with the current implementation.

If you perform a hardcoded +2 while loop, you'll remove the need of the if statements and at the same time be able to directly focus on extracting the data from each line.

The advice above is just the "cheat" version of your code. I have rewritten another version below.

First and foremost, you have read the first line with:

String line = reader.readLine();

And if we remove that,

while((line = reader.readLine()) != null) {
           newHashMap.put(line, reader.readLine());
        }

We'll shorten the code. If you look at the while loop, it actually assigns the line first, so we'll only have readLine within the put method by obtaining the even element which is in this case, the key's value.

So in short, the while loop carries the key data and the reader.readLine at the hashmap put method obtains the value data. Simple as that, you reduce the need for more memory addresses to be taken.

To further strengthen my answer, here's another overflow. Using BufferedReader to read Text File

You don't need to check whether lineCount is odd or even.

The description of readLine() in Java Docs , says

Reads a line of text. A line is considered to be terminated by any one of a line feed ('\\n'), a carriage return ('\\r'), or a carriage return followed immediately by a linefeed.

So, it reads one line at a time.

You can modify your code as:

private HashMap<String, String> newHashMap = new HashMap<String, String>();

    Charset charset = Charset.forName("US-ASCII");

    Path path = Paths.get("file_location");

    try (BufferedReader reader = Files.newBufferedReader(path, charset)) {

          String key = reader.readLine();
          String value = reader.readLine();

           while(key != null && value != null) {
              newHashMap.put(key, value);
              key = reader.readLine();
              value = reader.readLine();
}

I borrowed user @Scary Wombat's code in my answer. His code is aesthetically more pleasing, as well as ensures that you don't accidentally insert null values into the HashMap.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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