Как использовать общие типы списков в 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>();