57
votes

I have a file which contains data in the following format

1
2
3

I want to load this to map as {(1->1), (2->1), (3->1)}

This is the Java 8 code,

Map<Integer, Integer> map1 = Files.lines(Paths.get(inputFile))
                .map(line -> line.trim())
                .map(Integer::valueOf)
                .collect(Collectors.toMap(x -> x, x -> 1));

I am getting the following error

Exception in thread "main" java.lang.IllegalStateException: Duplicate key 1

How do I fix this error?

2
What would you like to happen when the file has the same number twice? - JB Nizet
If there is a situation like that, I want to get the number of occurrences as value for that key. So, if say key 2 is occurs 4 times in the file, then it would be (2->4). - pramodh
Then you'll need to use this method: docs.oracle.com/javase/8/docs/api/java/util/stream/… - JB Nizet
I think this question would be better if the sample data actually included a duplicate - matt freake
I faced the same issue, isn't the error message misleading ? The error message says duplicate key and prints out the value instead - Abhijeet

2 Answers

56
votes

The pramodh's answer is good if you want to map your value to 1. But in case you don't want to always map to a constant, the use of the "merge-function" might help:

Map<Integer, Integer> map1 = Files.lines(Paths.get(inputFile))
                .map(line::trim())
                .map(Integer::valueOf)
                .collect(Collectors.toMap(x -> x, x -> 1, (x1, x2) -> x1));

The above code is almost the same as posted in the question. But if it encounters a duplicate key, instead of throwing an exception, it will solve it by applying the merge function, by taking the first value.

26
votes

The code will run if there are no duplicates in the file.

Map<Integer, Integer> map1 = Files.lines(Paths.get(inputFile))
            .map(String::trim)
            .map(Integer::valueOf)
            .collect(Collectors.toMap(x -> x, x -> 1));

If there are duplicates use the following code to get the total number of occurrences in the file for that key.

Map<Integer, Long> map1 = Files.lines(Paths.get(inputFile))
            .map(String::trim)
            .map(Integer::valueOf)
            .collect(Collectors.groupingBy(x -> x, Collectors.counting());