Как использовать общие типы списков в java?

Ну, у меня есть класс Customer (без базового класса).

Мне нужно отправить из LinkedList в List. Есть ли какой-либо чистый способ сделать это?

Просто, чтобы вы знали, мне нужно отправить его в список. Другого типа не будет. (Я разрабатываю тестовое крепление с использованием Slim и FitNesse).


EDIT: Хорошо, мне кажется, мне нужно привести примеры кода здесь.

import java.util.*;
public class CustomerCollection
{
    protected LinkedList<Customer> theList;

    public CustomerCollection()
    {
        theList = new LinkedList<Customer>();
    }

    public void addCustomer(Customer c){ theList.add(c); }
    public List<Object> getList()
    {
        return (List<? extends Object>) theList;
    }
}

Итак, в соответствии с замечаниями Yuval A, я, наконец, написал код таким образом. Но я получаю эту ошибку:

CustomerCollection.java:31: incompatible types
found   : java.util.List<capture#824 of ? extends java.lang.Object>
required: java.util.List<java.lang.Object>
        return (List<? extends Object>)theList;
               ^
1 error

Итак, какой правильный способ сделать это?

Ответы

Ответ 1

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

Даже если вы хотите сбрасывать до List из Object, вы можете сделать это с помощью дженериков, как в следующем коде:

LinkedList<E> ll = someList;
List<? extends Object> l = ll; // perfectly fine, no casting needed

Теперь, после вашего редактирования, я понимаю, что вы пытаетесь сделать, и это невозможно, не создавая новый List так:

LinkedList<E> ll = someList;
List<Object> l = new LinkedList<Object>();
for (E e : ll) {
    l.add((Object) e); // need to cast each object specifically
}

и я объясню, почему это невозможно в противном случае. Рассмотрим это:

LinkedList<String> ll = new LinkedList<String>();
List<Object> l = ll; // ERROR, but suppose this was possible
l.add((Object) new Integer(5)); // now what? How is an int a String???

Дополнительные сведения см. в учебном пособии Java Java. Надеюсь, это разъяснит.

Ответ 2

Вот мое ужасное решение для кастингов. Я знаю, я знаю, я не должен выпускать что-то подобное в дикую природу, но это пригодится для каста любого объекта для любого типа:

public class UnsafeCastUtil {

    private UnsafeCastUtil(){ /* not instatiable */}

    /**
    * Warning! Using this method is a sin against the gods of programming!
    */
    @SuppressWarnings("unchecked")
    public static <T> T cast(Object o){
        return (T)o;
    }

}

Использование:

Cat c = new Cat();
Dog d = UnsafeCastUtil.cast(c);

Теперь я буду молиться богам программирования за свои грехи...

Ответ 3

Я сделал эту функцию для этого, уродливый, но он работает

public static <T> Collection<T> cast(Collection<? super T> collection, Class<T> clazz){
    return (Collection<T>)collection;
}

Ответ 4

>    public List<Object> getList()

Почему вы возвращаете List <Object> ? Вы можете также вернуть List (без generics), поскольку это эквивалентно, но сделает следующий код:

LinkedList<Customer> theList = new LinkedList<Customer>();

public List getList() {
    return theList;
}

Листинг между списками с разными типами типов является сложным и кажется ненужным здесь.

Конечно, вы должны возвращать тип List <Customer> ...

Ответ 5

LinkedList реализует List, поэтому вы можете реализовать

List< String > list1 = new LinkedList< String >(); 

Или вы хотите отличить из LinkedList <String> to List <int> ? в этом случае вам нужно выбрать каждый элемент и преобразовать его в целое число.

Ответ 6

Вы должны вернуть List<?> из своего метода. Интуитивно, getList() возвращает список, чтобы вызывающий мог получить элементы внутри. List<?> (что эквивалентно List<? extends Object>) позволяет эту функциональность. Однако вы не сможете вставить что-либо в него через возвращаемый список, потому что это не будет безопасным по типу; но я не думаю, что это то, что вам нужно в любом случае.

public List<?> getList()
{
    return theList;
}

Ответ 7

просто поместите

public static List<Object> getList() {
    List l = test;
    return l;
}

Ответ 8

Если ваш список имеет общий тип, например

ArrayList<String> strList = new ArrayList<String>(); strList.add("String1"); Object o = strList;

то Следующий метод должен работать

public <T> List<T> getListObjectInBodyOfType(Class<T> classz, Object body) {
    if(body instanceof List<?>){
        List<?> tempList = (List<?>)body;
        if(tempList.size() > 0 && tempList.get(0).getClass().equals(classz)){
            return (List<T>) body;
        }
    }
    return new ArrayList<T>();
}

Как его использовать?

List<String> strList1 = getListObjectInBodyOfType(String.class, o);

как я уже говорил, прежде чем он будет работать, если объект содержит общий список, это не будет работать, если вы передадите не общий список со смешанным типом элементов

Ответ 9

Список - это интерфейс, LinkedList - это конкретная реализация этого интерфейса. В большинстве случаев неявное приведение будет работать, назначить LinkedList в List или передать его функции, ожидающей список, и она должна просто "работать".

При необходимости может быть сделано явное приведение.

//This is valid
List<Customer> myList = new LinkedList<Customer>();

//Also Valid
List<Customer> myList = (List<Customer>) new LinkedList<Customer>();