Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java 8 toMap IllegalStateException Duplicate Key

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?

like image 453
pramodh Avatar asked Feb 27 '15 20:02

pramodh


People also ask

How do I fix Java Lang IllegalStateException duplicate key?

lang. IllegalStateException exception. To deal with the duplicate key introduce the mergeFunction as another argument. mergeFunction will resolve the duplicate key issue.

How do you handle duplicate keys in collectors toMap?

A recap on Collectors toMap It takes the key and the value mapper. Uses a throwing merger (throws an exception) as the default merge function when it encounters a duplicate key. It returns the result in an HashMap (it is an implementation detail – not to be relied upon). It takes the key and the value mapper.

Can Java HashMap have duplicate keys?

HashMap stores key, value pairs and it does not allow duplicate keys. If the key is duplicate then the old key is replaced with the new value.

How do I store duplicate keys on a map?

You can use a TreeMap with a custom Comparator in order to treat each key as unequal to the others. It would also preserve the insertion order in your map, just like a LinkedHashMap. So, the net result would be like a LinkedHashMap which allows duplicate keys!


2 Answers

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.

like image 141
KeyMaker00 Avatar answered Oct 02 '22 14:10

KeyMaker00


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()); 
like image 44
pramodh Avatar answered Oct 02 '22 12:10

pramodh