0

I'm trying to write a Java function which takes a List of Lists holding objects of any class, and then calculates the size of the set consisting of all different combinations of inner list objects, where all objects come from different lists. The algorithm is simple:

int combos(List<List<Object>> inList) {
    int res = 1;
    for(List<Object> list : inList) {
        res *= list.size();
    }
    return res;
}

But I'm getting this error when trying to run the function with a List<List<Integer>> object as input parameter:

List<List<Integer>> input = new ArrayList<List<Integer>>();
input.add(new ArrayList<Integer>());
input.get(0).add(1);
input.get(0).add(2);
combos(input);

The error:

The method combos(List<List<Object>>) in the type SpellChecker is not applicable for the arguments (List<List<Integer>>)

As far as I understand, Object is the parent class of Integer. So why doesn't this work? How can I make it work?

Sahand
  • 7,980
  • 23
  • 69
  • 137

4 Answers4

2

The relationship between Object and Integer does not apply to List<Object> and List<Integer>, see e.g. this related question for more details.

Use a type parameter:

<T> int combos(List<List<T>> inList) {
    int res = 1;
    for(List<T> list : inList) {
        res *= list.size();
    }
    return res;
}
Marvin
  • 13,325
  • 3
  • 51
  • 57
1

One solution is to use a type parameter in combos:

<T> int combos(List<List<T>> inList) {
    int res = 1;
    for(List<T> list : inList) {
        res *= list.size();
    }
    return res;
}
k_ssb
  • 6,024
  • 23
  • 47
1

This is closely related to this question about nested generics. The answer in that question provides some good info.

On top of the two good answers you already got here is another option.

public static void main(String[] args) {
    List<List<Integer>> input = new ArrayList<>();
    input.add(new ArrayList<>());
    input.get(0).add(1);
    input.get(0).add(2);
    combos(input);
}

static int combos(List<? extends List<?>> inList) {
    int res = 1;
    for (List<?> list : inList) {
        res *= list.size();
    }
    return res;
}
Jose Martinez
  • 11,452
  • 7
  • 53
  • 68
-1

This also works, if you don't need to specialize the List Datatype as List<Integer>

List<List<Object>> input = new ArrayList<List<Object>>();

input.add( new ArrayList<Object>() );

input.get( 0 ).add( new Integer(1) );
input.get( 0 ).add( new Integer(2) );


combos( input );
dark_982
  • 171
  • 2
  • 13
  • This doesn't actually answer the question. – k_ssb Apr 22 '18 at 13:57
  • Since he askey how he can make it work and this makes it work it does?! – dark_982 Apr 22 '18 at 13:59
  • 1
    OP wants to invoke `combos` with a `List>`, not `List>` – k_ssb Apr 22 '18 at 14:00
  • I don't see the big difference. either he has to edit the function or the function call since he did not specify which of both is fixed, I got a solution. But the problem is allready solved so the discussion is irrelevant :-D (EDIT) okay he specified in his question that the method is not fixed :-/ – dark_982 Apr 22 '18 at 14:03