如何让Java方法返回任何类型的通用列表?

80

我想编写一个方法,可以返回任何类型的java.util.List无需进行任何类型转换

List<User> users = magicalListGetter(User.class);

List<Vehicle> vehicles = magicalListGetter(Vehicle.class);

List<String> strings = magicalListGetter(String.class);

方法签名会是什么样子?也许是这样的:

public List<<?> ?> magicalListGetter(Class<?> clazz) {
    List<?> list = doMagicalVooDooHere();

    return list;
}

2
你想通过反射来填充列表吗?否则只需使用 new ArrayList<>() - Paul Bellora
9个回答

154
private Object actuallyT;

public <T> List<T> magicalListGetter(Class<T> klazz) {
    List<T> list = new ArrayList<>();
    list.add(klazz.cast(actuallyT));
    try {
        list.add(klazz.getConstructor().newInstance()); // If default constructor
    } ...
    return list;
}

方法也可以给一个泛型类型参数。你已经正确地推断出需要正确的类实例来创建东西 (klazz.getConstructor().newInstance())。


28

不需要甚至通过这门课程:

public <T> List<T> magicalListGetter() {
    return new ArrayList<T>();
}

3
想要添加物品,我认为您需要通过一个班级。 - zygimantus
如果您想操作列表并简单地返回相同类型,则这是最佳解决方案。(例如,反转顺序,减少项目数量等)只有在需要实例化T类型的新对象时才需要传递类。 - bhlowe

5
另一种选择是执行以下操作:
public class UserList extends List<User>{

}

public <T> T magicalListGetter(Class<T> clazz) {
    List<?> list = doMagicalVooDooHere();
    return (T)list;
}

List<User> users = magicalListGetter(UserList.class);

`


4

假设我们有一个List<Object> objectList,我们想要将其强制转换为List<T>

public <T> List<T> list(Class<T> c, List<Object> objectList){        
    List<T> list = new ArrayList<>();       
    for (Object o : objectList){
        T t = c.cast(o);
        list.add(t);
    }
    return list;
}

2
你可以使用旧的方法:
public List magicalListGetter() {
    List list = doMagicalVooDooHere();

    return list;
}

或者,您可以使用Object和所有内容的父类:

public List<Object> magicalListGetter() {
    List<Object> list = doMagicalVooDooHere();

    return list;
}

注意或许有一个更好的父类适用于你要放入列表中的所有对象。例如,Number 可以让你把 DoubleInteger 放在其中。


2

类似这样的


publiс <T> List<T> magicalListGetter(Class<T> clazz) {
    List list = doMagicalVooDooHere();
    return list;
}

1
为什么要传递 clazz 参数,如果你不打算使用它呢? - newacct
1
问题中是这样的,可能原帖作者会以某种方式使用它。 - Evgeniy Dorofeev

1
您可以简单地将其转换为List,然后检查每个元素是否可以转换为T。
public <T> List<T> asList(final Class<T> clazz) {
    List<T> values = (List<T>) this.value;
    values.forEach(clazz::cast);
    return values;
}

0

给定一些遗留代码,它返回一个未经类型化的List

List list = database.GetCustomers(); //legacy code returns untyped list

我们将使用一个辅助函数:

public static <T> @NotNull List<T> castList(final @NotNull Iterable sourceList)
{
    List<T> result = new ArrayList<>();
    for (Object o : sourceList)
        result.add((T)o);

    return result;
}

将返回的列表转换为通用类型的 List<T>

List<Customer> = castList(database.GetCustomers()); //cast the list the appropriate type

为什么Java没有扩展方法,这真的让我感到困惑。


原始类型是子类型。一个简单的 List<Customer> customers = (List<Customer>) list; 就足够了。 - Johannes Kuhn

-1

我相信你可以完全删除 <stuff>,这将生成一个警告,你可以使用 @suppresswarnings。如果你真的想要它是通用的,但要使用它的任何元素,你将不得不进行类型转换。例如,我编写了一个简单的冒泡排序函数,并在对列表进行排序时使用了通用类型,实际上,在这种情况下,它是Comparable的数组。如果你想使用一个项目,做类似这样的事情:System.out.println((Double)arrayOfDoubles[0] + (Double)arrayOfDoubles[1]);因为我把Double(s)塞进了Comparable(s)中,这是多态性,因为所有的Double(s)都继承自Comparable,以便通过Collections.sort()轻松排序。

        //INDENT TO DISPLAY CODE ON STACK-OVERFLOW
@SuppressWarnings("unchecked")
public static void simpleBubbleSort_ascending(@SuppressWarnings("rawtypes") Comparable[] arrayOfDoubles)
{
//VARS
    //looping
    int end      =      arrayOfDoubles.length - 1;//the last index in our loops
    int iterationsMax = arrayOfDoubles.length - 1;

    //swapping
    @SuppressWarnings("rawtypes")
    Comparable tempSwap = 0.0;//a temporary double used in the swap process
    int elementP1 = 1;//element + 1,   an index for comparing and swapping


//CODE
    //do up to 'iterationsMax' many iterations
    for (int iteration = 0; iteration < iterationsMax; iteration++)
    {
        //go through each element and compare it to the next element
        for (int element = 0; element < end; element++)
        {
            elementP1 = element + 1;

            //if the elements need to be swapped, swap them
            if (arrayOfDoubles[element].compareTo(arrayOfDoubles[elementP1])==1)
            {
                //swap
                tempSwap = arrayOfDoubles[element];
                arrayOfDoubles[element] = arrayOfDoubles[elementP1];
                arrayOfDoubles[elementP1] = tempSwap;
            }
        }
    }
}//END public static void simpleBubbleSort_ascending(double[] arrayOfDoubles)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接