Omen
Omen

Reputation: 43

How to read a text file and store with hashmap?

I have a text file with integers in 3 columns and with multiple entries for each number on the first column, like the sample above:

1 23 1
1 24 2
1 57 1
1 10 1
1 59 2
1 31 2
1 38 1
1 11 1
2 39 2
2 40 1
2 15 1
2 74 2

I can read the contents of the file with the code shown above

public static void main(String[] args) {

    try (BufferedReader br = new BufferedReader(new FileReader("/home/user/Desktop/file.txt")))
        {
            String sCurrentLine;
            while ((sCurrentLine = br.readLine()) != null) {
                System.out.println(sCurrentLine);
            }
        } 
    catch (IOException e) {
                e.printStackTrace();
        } }

but I want to use hashmap to join all the entries for every different number of the first column in one line like this:

1 23 1 24 2 57 1 10 1 59 2 31 2 38 1
2 39 2 40 1 15 1 74 2

Do you have any suggestion? Thanks!

Upvotes: 0

Views: 11744

Answers (3)

Omen
Omen

Reputation: 43

Below is the code that worked for me better and shows all numbers aggregated for each different number in the first column. Thank you all for posting a solution. If you suggest any kind of change on this, please feel free to do so.

public static void main(String[] args) {

    String sCurrentLine;
    TreeMap<Integer, ArrayList<Integer[]>> rowMap = new TreeMap<Integer, ArrayList<Integer[]>>();
    try (BufferedReader br = new BufferedReader(new FileReader("/home/user/Desktop/file.txt")))
        {
            while ((sCurrentLine = br.readLine()) != null) {

                String[] cols = sCurrentLine.split(" ");

                if (cols.length < 1) {
                }

                try {
                    int colKey = Integer.parseInt(cols[0]);

                    Integer[] colValues = new Integer[cols.length - 1];

                    for (int i = 1; i < cols.length; i++) {
                        colValues[i - 1] = Integer.parseInt(cols[i]);
                    }

                    if (!rowMap.containsKey(colKey)) {
                        rowMap.put(colKey, new ArrayList<Integer[]>());
                    }
                    rowMap.get(colKey).add(colValues);
                } catch (NumberFormatException e) {
                }
                for (Integer key : rowMap.keySet()) {
                    String row = key + ""; 
                    for (Integer[] rows : rowMap.get(key)) {
                        for (Integer col : rows) {
                            row += " " + col;
                        }
                    }
                    System.out.println(row);
                }
    }
    catch (IOException e) {
            e.printStackTrace();
    }
}

Upvotes: 0

Radiodef
Radiodef

Reputation: 37845

Here is some basic code to get you started. This uses a TreeMap which will sort the entries. Read the blurb on HashMap to see why, which specifies that HashMap guarantees no ordering of the entries. It would be possible to use HashMap for this but I don't recommend it because you might have to make extra steps somewhere.

TreeMap<Integer, ArrayList<Integer[]>> rowMap = new TreeMap<Integer, ArrayList<Integer[]>>();

// when you have your new line

String[] cols = sCurrentLine.split(" ");

if (cols.length < 1) {
    // handle error if there is not a key column
}

try {
    int colKey = Integer.parseInt(cols[0]);

    Integer[] colValues = new Integer[cols.length - 1];

    for (int i = 1; i < cols.length; i++) {
        colValues[i - 1] = Integer.parseInt(cols[i]);
    }

    if (!rowMap.containsKey(colKey)) {

        // add a new entry for this column number
        rowMap.put(colKey, new ArrayList<Integer[]>());
    }

    rowMap.get(colKey).add(colValues);

} catch (NumberFormatException e) {
    // handle error if any columns don't have integers
}

Now what you have is a TreeMap containing a listing of all rows grouped by the number in column 1.

For your example document to print the entire map you can do the following:

// iterate by column 1 number in numerical order
for (Integer key : rowMap.keySet()) {

    // iterate by rows in this column in the order they were added
    for (Integer[] row : rowMap.get(key)) {
        String printout = key + ":";

        // iterate by columns in this row
        for (Integer col : row) {
            printout += " " + col;
        }

        System.out.println(printout);
    }
}

This will output the following:

1: 23 1
1: 24 2
1: 57 1
1: 10 1
1: 59 2
1: 31 2
1: 38 1
1: 11 1
2: 39 2
2: 40 1
2: 15 1
2: 74 2

So you can see this sorts your document based on the value in column 1. You could also print them in the format you showed in the OP, you'd just change the loop a little bit so the rows are added to the same line.

Some notes about using TreeMap this way:

  • The numbers in column 1 can be any integer.
  • The numbers in column 1 can be in any order.
  • The rows can have any number of columns beyond the first one.

But when you list them using the Map they will always be grouped by the column 1 number and they will always be ordered numerically.

It could be somewhat simplified if you don't care about keeping the rows sorted as well in which case you can make a TreeMap<Integer, ArrayList<Integer>> or TreeMap<Integer, ArrayList<String>> or even a TreeMap<Integer, String> if all you do is concatenate each row.

Upvotes: 2

Vae
Vae

Reputation: 60

A HashMap is an Object that maps a Key to a specific value. This is an implementation of what tobias_k is suggesting:

HashMap<int, String> map = new HashMap<int,String>();

public static void main(String[] args) {

    try (BufferedReader br = new BufferedReader(new FileReader("/home/user/Desktop/file.txt")))
        {
            String sCurrentLine;
            while ((sCurrentLine = br.readLine()) != null) {
                // ** NEW CODE **
                // get first int in current line
                int first = Integer.parseInt(sCurrentLine.substring(0, sCurrentLine.indexOf(" ")))
                // get rest of line
                String rest = sCurrentLine.substring(sCurrentLine.indexOf(" ")).trim();
                // get what is currently in for key value and append to it what you just got
                map.put(first, map.get(first) + rest);

                System.out.println(sCurrentLine);
            }
        } 
    catch (IOException e) {
                e.printStackTrace();
        } } 

And to print, you could do:

for(int key : map.keySet()) {
    System.out.println(map.get(key));
}

DISCLAIMER may not be 100% valid syntax

Upvotes: 1

Related Questions