Cast Set to Iterable

Alexander Mills :

I have this static method:

  static <V, T, E> void GroupToSets(
    final Iterable<T> items,
    final Asyncc.IAsyncCallback<Map<String, Set<V>>, E> f) {

    final HashMap<String, Set<V>> results = new HashMap<>();
    final Iterator<T> iterator = items.iterator();

    if (!iterator.hasNext()) {
      f.done(null, results);
      return;
    }


    RunMap((Map<String, Iterable<V>>)results, f);

  }

And I am calling this:

  private static <T, V, E> void RunMap(
    final Map<String, Iterable<V>> results,
    final Asyncc.IAsyncCallback<Map<String, Iterable<V>>, E> f) { ... }

the problem is for some reason I can't cast a Set<V> to Iterable<V>...I am looking for a supertype for both List<V> and Set<V>, I thought Iterable would do that but apparently not?

The error I am getting is:

Inconvertible types; cannot cast

'java.util.HashMap<java.lang.String,java.util.Set<V>>' to

'java.util.Map<java.lang.String,java.lang.Iterable<V>>'

I am also trying to cast List<V> to Iterable<V> as I mentioned I am looking for a supertype for both List and Set..maybe just use Collection?

Update, I tried using:

final Map<String, Collection<V>> results

instead of

final Map<String, Iterable<V>> results

I get the same problem.

Adam Siemion :

Change the RunMap declaration to:

private static <V, E, T extends Iterable<V>> void RunMap(
    final Map<String, T> results,
    final Asyncc.IAsyncCallback<Map<String, T>, E> f) {

Generics in Java are not covariance, it means when RunMap expects a Map<String, Iterable<V>> you cannot pass to it a Map<String, Set<V>> instance.

To solve this you can use a bounded wildcard ? extends Vector<V>, however there is a correlation between the two RunMap arguments. The type of the values in the the two maps must be the same, therefore you need to define a method type T extends Iterable<V> and use it when defining the type of the method arguments: Map<String, T> and Asyncc.IAsyncCallback<Map<String, T>, E>.

You can make the declaration a bit shorter by defining M extends Map<String, ? extends Iterable<V>>:

private static <V, E, M extends Map<String, ? extends Iterable<V>>> void RunMap(
    final M results,
    final Asyncc.IAsyncCallback<M, E> f) {

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=144215&siteId=1