1

I've this simple interface:

public interface Transportable<T> { 
  public T getTransport();
}

and a lot of classes that provide implementation, ie:

class A implements Transportable<ATransport> {
  public ATransport getTransport() {
    ATransport at=new ATransport();
    [...]
    return at;
  }
}
class B implements Transportable<BTransport> {
  public BTransport getTransport() {
    BTransport bt=new BTransport();
    [...]
    return bt;
  }
}

also I've lists of transportables objects, like this:

LinkedList<A> aList=new LinkedList<>();

and I want to call the getTransport method for all elements in aList, obtaining a LinkedList, doing something like that:

LinkedList<ATransport> atList = getTransport(aList);
LinkedList<BTransport> btList = getTransport(bList);

I don't want to write a foreach for every class I have, is there a way to implement this using generics? like:

public <T> List<???> getTransport(List<T> list)

or something similar? I've tried but without luck, I think I'm missing something about generics and about the difference between using or etc...

Thank you!

5
  • 2
    Are you using Java 8 by any chance? Commented Jun 18, 2014 at 18:41
  • 3
    Would this help? public static <U, T extends Transportable<U>> List<U> getTransport(List<T> list) Commented Jun 18, 2014 at 18:42
  • @arshajii, unfortunately no. Commented Jun 18, 2014 at 18:52
  • @GáborBakos, I'll give it a try. If it works would you mind to post it as an answer so I can accept it? - thank you Commented Jun 18, 2014 at 18:53
  • it works! thanks! I've to study more... can you provide some links to a clear tutorial with examples? Commented Jun 18, 2014 at 19:32

1 Answer 1

2

This seems to be working:

package dummy;

import java.util.Collections;
import java.util.LinkedList;
import java.util.List;

class ATransport{}
class BTransport{}
class A implements Transportable<ATransport> {
  public ATransport getTransport() {
    ATransport at=new ATransport();
    return at;
  }
}
class B implements Transportable<BTransport> {
  public BTransport getTransport() {
    BTransport bt=new BTransport();
    return bt;
  }
}
class X {
    public static <U, T extends Transportable<U>> List<U> getTransport(List<T> list) {
        List<U> ret = new LinkedList<>();
        for (T t : list) {
            ret.add(t.getTransport());
        }
        return ret;
    }

    public static void main(String[] args) {
        List<BTransport> transportsB = getTransport(Collections.singletonList(new B()));
        List<ATransport> transportsA = getTransport(Collections.singletonList(new A()));
    }
}

The idea behind this is that we name the type we need and what we get. The only trick is to create as a static method, so the type inference is working there. (Just like in the Collections.singletonList call.)

Edit: This is a tutorial for generics explaining the static method trick and some other type inference use cases. This seems to be a useful resource for generics. The basic idea (naming the other type and using in the bound) might have a more general name that I am unaware of, sorry for not giving a reference to that.

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.