Как я могу создать список с использованием дженериков в Java?

Обратите внимание на следующий фрагмент:

public interface MyInterface {

    public int getId();
}

public class MyPojo implements MyInterface {

    private int id;

    public MyPojo(int id) {
        this.id = id;
    }

    public int getId() {
        return id;
    }

}

public ArrayList<MyInterface> getMyInterfaces() {

    ArrayList<MyPojo> myPojos = new ArrayList<MyPojo>(0);
    myPojos.add(new MyPojo(0));
    myPojos.add(new MyPojo(1));

    return (ArrayList<MyInterface>) myPojos;
}

Оператор return выполняет кастинг, который не компилируется. Как преобразовать список myPojos в более общий список, без необходимости проходить через каждый элемент списка?

Спасибо

Ответ 1

Измените способ использования шаблона:

public ArrayList<? extends MyInterface> getMyInterfaces() {    
    ArrayList<MyPojo> myPojos = new ArrayList<MyPojo>(0);
    myPojos.add(new MyPojo(0));
    myPojos.add(new MyPojo(1));

    return myPojos;
}

Это не позволит вызывающему пользователю попытаться добавить другие реализации интерфейса в список. Кроме того, вы можете просто написать:

public ArrayList<MyInterface> getMyInterfaces() {
    // Note the change here
    ArrayList<MyInterface> myPojos = new ArrayList<MyInterface>(0);
    myPojos.add(new MyPojo(0));
    myPojos.add(new MyPojo(1));

    return myPojos;
}

Как обсуждалось в комментариях:

  • Возвращение подстановочных коллекций может быть неудобным для вызывающих абонентов.
  • Обычно лучше использовать интерфейсы вместо конкретных типов для возвращаемых типов. Таким образом, предлагаемая подпись, вероятно, будет одной из следующих:

    public List<MyInterface> getMyInterfaces()
    public Collection<MyInterface> getMyInterfaces()
    public Iterable<MyInterface> getMyInterfaces()
    

Ответ 2

Выбор правильного типа с самого начала лучше всего, однако, чтобы ответить на ваш вопрос, вы можете использовать стирание типа.

return (ArrayList<MyInterface>) (ArrayList) myPojos;

Ответ 3

Вы должны делать:

public ArrayList<MyInterface> getMyInterfaces() {   
   ArrayList<MyInterface> myPojos = new ArrayList<MyInterface>(0);    
   myPojos.add(new MyPojo(0));    
   myPojos.add(new MyPojo(1));    
   return myPojos;
}

Ответ 4

В этом случае я бы сделал это следующим образом:

public ArrayList<MyInterface> getMyInterfaces() {

    ArrayList<MyInterface> myPojos = new ArrayList<MyInterface>(0);
    myPojos.add(new MyPojo(0));
    myPojos.add(new MyPojo(1));

    return myPojos;
}

MyPojo ist типа MyInterface (поскольку он реализует интерфейс). Это означает, что вы можете просто создать список с необходимым интерфейсом.

Ответ 5

Попробуйте использовать интерфейсы везде, кроме случаев, когда вы создаете экземпляры, и проблемы будут уходить:

public List<MyInterface> getMyInterfaces()
{
    List<MyInterface> myInterfaces = new ArrayList<MyInterface>(0);
    myInterfaces.add(new MyPojo(0));
    myInterfaces.add(new MyPojo(1));

    return myInterfaces;
}

Как уже говорили другие, использование MyInterface устраняет вашу проблему. Также лучше использовать интерфейс List вместо ArrayList для возвращаемых типов и переменных.