A while ago I had found the following info about a cleaner way to initialize maps with Java 8: http://minborgsjavapot.blogspot.com/2014/12/java-8-initializing-maps-in-smartest-way.html .
Using those guidelines, I had implemented the following class in one application:
public class MapUtils {
public static <K, V> Map.Entry<K, V> entry(K key, V value) {
return new AbstractMap.SimpleEntry<>(key, value);
}
public static <K, U> Collector<Map.Entry<K, U>, ?, Map<K, U>> entriesToMap() {
return Collectors.toMap((e) -> e.getKey(), (e) -> e.getValue());
}
public static <K, U> Collector<Map.Entry<K, U>, ?, ConcurrentMap<K, U>> entriesToConcurrentMap() {
return Collectors.toConcurrentMap((e) -> e.getKey(), (e) -> e.getValue());
}
}
In that application, I had implemented code like this:
public Map<String, ServiceConfig> serviceConfigs() {
return Collections.unmodifiableMap(Stream.of(
entry("ActivateSubscriber", new ServiceConfig().yellowThreshold(90).redThreshold(80)),
entry("AddAccount", new ServiceConfig().yellowThreshold(90).redThreshold(80).rank(3)),
...
).
collect(entriesToMap()));
}
This code is working perfectly fine.
In a different application, I copied the MapUtils class into a package, and I imported that class in one class the same way I did in the other application.
I entered the following to reference this:
Map<String, USLJsonBase> serviceRefMap =
Collections.unmodifiableMap(Stream.of(
entry("CoreService", coreService),
entry("CreditCheckService", creditCheckService),
entry("PaymentService", paymentService),
entry("AccountService", accountService),
entry("OrdercreationService", orderCreationService),
entry("ProductAndOfferService", productAndOfferService),
entry("EquipmentService", equipmentService),
entry("EvergentService", evergentService),
entry("FraudCheckService", fraudCheckService)
).
collect(entriesToMap()));
On the "collect" call, Eclipse is telling me the following:
The method collect(Collector<? super Map.Entry<String,? extends USLJsonBase>,A,R>) in the type Stream<Map.Entry<String,? extends USLJsonBase>> is not applicable for the arguments (Collector<Map.Entry<Object,Object>,capture#1-of ?,Map<Object,Object>>)
What simple and completely non-obvious change is required to get this to work?
Update:
I thought that adding a type hint might do it, but I don't understand why the usage in the other application did not require this.
I changed the reference to this, which now doesn't give me a compile error:
Map<String, USLJsonBase> serviceRefMap =
Collections.unmodifiableMap(Stream.<Map.Entry<String, USLJsonBase>>of(
entry("CoreService", coreService),
entry("CreditCheckService", creditCheckService),
entry("PaymentService", paymentService),
entry("AccountService", accountService),
entry("OrdercreationService", orderCreationService),
entry("ProductAndOfferService", productAndOfferService),
entry("EquipmentService", equipmentService),
entry("EvergentService", evergentService),
entry("FraudCheckService", fraudCheckService)
).
collect(entriesToMap()));
Again, why was the type hint required here, but not in the other application? The only difference is that the other application is returning the map from a function, and the new code is assigning the map to a local variable. I also modified it so that instead of storing into a local variable, I'm passing it to another method (which was the original need). That didn't change the need to add the type hint.