5 Replies Latest reply: Jun 12, 2010 12:25 PM by 843793 RSS

    Getting element type of generic list

    843793
      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
          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
            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
              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
                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
                  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