This discussion is archived
5 Replies Latest reply: Jun 12, 2010 10:25 AM by 843793 RSS

Getting element type of generic list

843793 Newbie
Currently Being Moderated
Hello,

I have the following code, which generates a compiler error on the f(x) call:
import java.util.*;

class Test {
  static <T extends Comparable<T>> void f( List<T> l ) {}
  static <E extends List<? extends Comparable<?>>> E g( E x ) {
    // <T>f(java.util.List<T>) in Test cannot be applied to (E)
    f(x);
    return x;
  }
}
my f-method computes the next permutation of the list in-place.
Instead of a method g, I have a class that implements Iterator<E>.
When my iterator is constructed with an ArrayList<Integer>, I want the next()-method to return an ArrayList<Integer>, and the superclass List<Integer>

The Problem here seems to be, that the compiler can't infer that "?" should be "T".

I'm certain my attempt is way too complicated, all I want is to keep f() in the current form, as a generic helper method, and an iterator-class, that computes the permutations using f(), and returns them in the type of the original list.


Thanks for helping!
  • 1. Re: Getting element type of generic list
    EJP Guru
    Currently Being Moderated
    static <E extends List<? extends Comparable<?>>> E g( E x ) {
    The problem is that the two ? aren't the same thing. If they're meant to be the same, make them the same:
    static <T, E extends List<T extends Comparable<T>>> E g( E x ) {                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               
  • 2. Re: Getting element type of generic list
    843793 Newbie
    Currently Being Moderated
    Thanks for the quick answer!

    Now I have a syntax error:
    min.java:6: > expected
         static <T, E extends List<T[here] extends Comparable<T>>> E g( E x )
    min.java:6: <identifier> expected
         static <T, E extends List<T extends Comparable<T>[here]>> E g( E x )
    And with
    static <T, E extends List<? extends Comparable<T>>> E g( E x )
    there is no syntax error, but the same as in the original post.

    But this definition works:
    static <T extends Comparable<T>, E extends List<T>> E g( E x )
    Although, when I try to use the same definition in a class:
    class Iter<T extends Comparable<T>, E extends List<T>> implements Iterator<E>
    T is not inferred, I have to use
    (new Iter<Integer, ArrayList<Integer>>(a)).next(); // works
    (new Iter<ArrayList<Integer>>(a)).next(); // wrong number of type arguments
    (new Iter(a)).next(); // unchecked
    Is there a way to infer T? In theory, it should be possible, since we know E extends List<T>, and it works for functions...
  • 3. Re: Getting element type of generic list
    843793 Newbie
    Currently Being Moderated
    Hello Pascal,
    But this definition works:
    static <T extends Comparable<T>, E extends List<T>> E g( E x )
    I'm sure that's what ejp meant to write, that's the correct solution.
    Is there a way to infer T? In theory, it should be possible, since we know E extends List<T>, and it works for functions...
    Java's type inference is rather conservative. As I understand it there was at least one previous algorithm which proved to be unsound, so I wager they wanted to err on the side of caution.

    There is an [OOPSLA08 paper|http://www.cs.rice.edu/~dlsmith/java-type-system-oopsla08.pdf] that goes into more detail and presents a very neat upgrade which should handle this case.

    With kind regards
    Ben
  • 4. Re: Getting element type of generic list
    843793 Newbie
    Currently Being Moderated
    The following works:
    import java.util.*;
    
    class Test {
      static <T extends Comparable<T>> void f( List<T> l ) {}
      static <E extends Comparable<E>> List<E> g( List<E> x ) {
        f(x);
        return x;
      }
    }
    The problem is that, as it has been said, the following types:

    1) List<? extends Comparable<?>> and
    2) List<T> (where T extends Comparable<T>)

    are two different beasts for the compiler (and the language spec).

    Edited by: maurizio.cimadamore on Jun 10, 2010 1:55 AM
  • 5. Re: Getting element type of generic list
    843793 Newbie
    Currently Being Moderated
    Hey Maurizio,

    just wanted to say that it's great you're posting here. I hope work on lambda-dev is going well.

    (Sorry for going OT.)

    With kind regards
    Ben