3

I have a MultiValueMap<Integer, Path> from which I am trying to get [print for the purpose of this question] out all the paths which were put in the map using the same key.

This is my current solution:

MultiValueMap<Integer, Path> duplicates = duplicateFinder.getDuplicates();

for (Map.Entry<Integer, Object> entry: duplicates.entrySet()) {
  final Integer key = entry.getKey();
  final Object obj = entry.getValue();
  for (Object o: (LinkedList)((ArrayList)entry.getValue()).get(0))
    System.out.println(o);
  System.out.println();
}

I feel my solution is dangerous (casting and magic number 0) and would like to avoid it. How can I achieve the desired result in a more readable/safe manner?

Pétur Ingi Egilsson
  • 4,368
  • 5
  • 44
  • 72
  • @SotiriosDelimanolis Error:(35, 41) java: incompatible types: java.lang.Object cannot be converted to java.util.List – Pétur Ingi Egilsson Apr 01 '15 at 18:50
  • How do you mean by not declared as `MultiValueMap`? The decleration is shown in the first line of my code listing. – Pétur Ingi Egilsson Apr 01 '15 at 18:52
  • 1
    @SotiriosDelimanolis: I agree that would make sense, but that's not what the API documentation appears to support. – Jon Skeet Apr 01 '15 at 18:59
  • I found the error. It was elsewhere in the program. `MultiValueMap` was being populated with `LinkedList`s containing `Path`s instead of `Path`s. I feel its strange that it does not ensure that whatever I try putting in there is a `Path`. – Pétur Ingi Egilsson Apr 01 '15 at 19:02
  • 1
    @Pétur It's because they've inexplicably made it implement `Map`; They couldn't make it implement `Map` because then an entry would be an `Entry`. They couldn't make it implement `Map>` because then the `put` method would need a `Collection` not a `V`, so to get round this they've made it implement `Map`, which takes away any chance of type-safety. It looks like you should use the Guava version instead. – Paul Boddington Apr 01 '15 at 19:10
  • @pbabcdefp Thank you for the good explaination. – Pétur Ingi Egilsson Apr 01 '15 at 19:28

1 Answers1

4

The entry set seems to be declared with an unfortunate signature. But you could iterate over the keys instead, and call getCollection for each:

for (Integer key : duplicates.keySet()) {
    Collection<Path> paths = duplicates.getCollection(key);
    System.out.println("Paths for " + key);
    for (Path path : paths) {
        System.out.println("  " + path);
    }
    System.out.println();
}

(Note that Guava's Multimap would allow you to use duplicates.asMap().entrySet() instead, and each entry would have a Collection<V> as a value...)

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194