Konstantin Solomatov
Konstantin Solomatov

Reputation: 10332

How to create a list with complex structure inside

I have the following two classes:

class Key<T1, T2> {}
class Pair<F, S> {}

I want to create a map from Key<T1, T2> to List<Pair<T1, T2>> where T1 and T2 are different for each map's entry. I am trying to implement it this way:

class KeyToListMap {
  private Map<Key<?, ?>, List<Pair<?, ?>>> myItems = new HashMap<Key<?, ?>, List<Pair<?, ?>>>();


  public<T1, T2> List<Pair<T1, T2>> getList(Key<T1, T2> key) {
    if (!myItems.containsKey(key)) {
      myItems.put(key, new ArrayList<Pair<T1, T2>>());
    }
    return (List<Pair<T1, T2>>) myItems.get(key);
  }
}

However I got two type errors:

put(test.Key<?,?>,java.util.List<test.Pair<?,?>>) in java.util.Map<test.Key<?,?>,java.util.List<test.Pair<?,?>>> cannot be applied to (test.Key<T1,T2>,java.util.ArrayList<test.Pair<T1,T2>>)

inconvertible types
found   : java.util.List<test.Pair<?,?>>
required: java.util.List<test.Pair<T1,T2>>

How can I express this in Java without resorting to using raw types?

Upvotes: 2

Views: 595

Answers (4)

Konstantin Solomatov
Konstantin Solomatov

Reputation: 10332

I implemented it like this:

class Key<T1, T2> {
}

class Pair<F, S> {

}

class KeyToListMap {
  private Map<Key<?, ?>, List<? extends Pair<?, ?>>> myItems = new HashMap<Key<?, ?>, List<? extends Pair<?, ?>>>();

  public<T1, T2> List<Pair<T1, T2>> getList(Key<T1, T2> key) {
    if (!myItems.containsKey(key)) {
      myItems.put(key, new ArrayList<Pair<T1, T2>>());
    }
    return (List<Pair<T1, T2>>) myItems.get(key);
  }
}

However it's kind of hack. Does anyone know a better answer?

Upvotes: 0

Ramon
Ramon

Reputation: 8424

There is no way to do this. The problem here is that you want the map value type to depend on the key type. The use of generics here is actually not the issue. For example, there is no way to declare that a map has integer keys always associated with integer values and string keys associated with string values. You will always have to type the keys and values as a common supertype (probably Object) and cast to the expected type.

Upvotes: 1

plucury
plucury

Reputation: 1120

You can assign the map as below

private Map<Key<T1, T2>, List<Pair<F, S>>> myItems = new HashMap<Key<T1, T2>, List<Pair<F, S>>>();

Upvotes: -1

aviad
aviad

Reputation: 8278

Use

? extends

in Map declaration

Upvotes: 3

Related Questions