sergey_208
sergey_208

Reputation: 651

how to create TreeMap with <Integer, List<Integer>> from a two-column txt file

I am reading a txt file having two columns where each element is an integer. I'd like to use the elements in the first column as a key, and the elements in the second column as my value.

I am sharing just a small portion of my data set.

0   1
0   2
0   3
0   4
1   2
1   3
1   0
Scanner scanner = new Scanner(new FileReader(DATADIR+"data.txt"));
TreeMap<Integer, List<Integer>> myMap = new TreeMap<Integer, List<Integer>>();
while (scanner.hasNextLine()) {
  String[] line= scanner.nextLine().split("\t");

}

Now, what I need is to have a structure with which when I call 0, I should get <1,2,3,4>.

Upvotes: 0

Views: 155

Answers (3)

deHaar
deHaar

Reputation: 18578

I wouldn't use a Scanner at all for reading a file. Instead, use a modern way of streaming the file content and then handle each line as desired.

In my environment, splitting a file by "\t" just does not work, that's why I split a String containing an arbitrary amount of whitespaces between the desired values by an arbitrary amount of whitespaces.

See the following minimal example:

public static void main(String[] args) {
    Path filePath = Paths.get(DATADIR).resolve(Paths.get("data.txt"));

    // define the map
    Map<Integer, List<Integer>> map = new TreeMap<>();

    try {
        // stream all the lines read from the file
        Files.lines(filePath).forEach(line -> {
            // split each line by an arbitrary amount of whitespaces
            String[] columnValues = line.split("\\s+");
            // parse the values to int
            int key = Integer.parseInt(columnValues[0]);
            int value = Integer.parseInt(columnValues[1]);
            // and put them into the map,
            // either as new key-value pair or as new value to an existing key
            map.computeIfAbsent(key, k -> new ArrayList<>()).add(value);
        });
    } catch (IOException e) {
        e.printStackTrace();
    }

    // print the map content
    map.forEach((key, value) -> System.out.println(key + " : " + value));
}

You will have to use the following imports along with the ones you have:

import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

Upvotes: 1

HPCS
HPCS

Reputation: 1454

You can try this:

  TreeMap<Integer, List<Integer>> myMap = new TreeMap<Integer, List<Integer>>();
        while (scanner.hasNextLine()) {
            String[] line = scanner.nextLine().split("\\s+");               
            myMap.computeIfAbsent(Integer.valueOf(line[0]), k -> new ArrayList<>()).add(Integer.valueOf(line[1]));
        }
        System.out.println(myMap );

Upvotes: 1

Abhishek Garg
Abhishek Garg

Reputation: 2288

You should check if the key exists in map and add accordingly. Sample code:

final Scanner scanner = new Scanner(new FileReader(DATADIR + "data.txt"));
        final TreeMap<Integer, List<Integer>> myMap = new TreeMap<Integer, List<Integer>>();
        while (scanner.hasNextLine()) {
            final String[] line = scanner.nextLine().split("\t");
            final Integer key = Integer.parseInt(line[0]);
            final Integer value = Integer.parseInt(line[1]);
            if (myMap.containsKey(key)) {
                myMap.get(key).add(value);
            } else {
                final List<Integer> valueList = new LinkedList<>();
                valueList.add(value);
                myMap.put(key, valueList);
            }
        }

Upvotes: 1

Related Questions