Reputation: 175
I m trying to convert List
of available Currency
to a Map
, To look up based on Currency Numeric code i want to get String code. Here is the code.
But this code above throwing below error, I m very new to Java 8 hence banging my head :
Exception in thread "main" java.lang.ExceptionInInitializerError
Caused by: java.lang.IllegalStateException: Duplicate key YUM
at java.util.stream.Collectors.lambda$throwingMerger$0(Collectors.java:133)
at java.util.HashMap.merge(HashMap.java:1254)
at java.util.stream.Collectors.lambda$toMap$58(Collectors.java:1320)
at java.util.stream.ReduceOps$3ReducingSink.accept(ReduceOps.java:169)
at java.util.HashMap$KeySpliterator.forEachRemaining(HashMap.java:1556)
at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708)
at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499)
But this code above throwing below error, I m very new to Java 8 hence banging my head
public class IsoCurrencyCode {
private static final Set<Currency> ISO_CURRENCY = Currency.getAvailableCurrencies();
private static final Map<Integer, Currency> NUMERIC_MAP = ISO_CURRENCY.stream().collect(Collectors.toMap(Currency::getNumericCode, Function.identity()));
public static void main(String[] args) {
//
Currency currency = NUMERIC_MAP.get(971);
System.out.println(currency.getCurrencyCode());
}
}
It should load all currencies into the map with code as keys.
Upvotes: 2
Views: 10897
Reputation: 131496
Collectors.toMap()
doesn't accept duplicates for keys.
Since you have that for Currency::getNumericCode
, toMap()
throws this exception when a duplicate key is encountered.
Caused by: java.lang.IllegalStateException: Duplicate key YUM
Note that here the error message is misleading. Keys are Integer
while YUM
is not. YUM
looks like a Currency
instance and that is.
Indeed, YUM
refers to one of the values (Currency
) processed by toMap()
that have a duplicate key, not the key value itself. It is a Java bug fixed in Java 9.
To solve your issue, either use Collectors.groupingBy()
to collect to a Map<Integer, List<Currency>>
and in this case you could have multiple values by key or as alternative merge the duplicate keys with the toMap()
overload, for example to keep the last entry :
private static final Map<Integer, Currency> NUMERIC_MAP =
ISO_CURRENCY.stream()
.collect(Collectors.toMap(Currency::getNumericCode, Function.identity(), (v1, v2)-> v2);
To answer to your comment, you could find the culprit code (duplicates) in this way :
Map<Integer, List<Currency>> dupMap =
ISO_CURRENCY.stream()
.collect(Collectors.groupingBy(Currency::getNumericCode)
.entrySet()
.filter(e -> e.getValue().size() > 1)
.collect(Collectors.toMap(Entry::getKey,Entry::getValue));
System.out.println(dupMap);
Upvotes: 8