在方法中创建与ArrayList参数相同的类型ArrayList

时间:2014-10-26 22:02:38

标签: java generics

我正在用Java实现mergesort。我希望它能够与每个可以比较的对象一起工作。

这是代码

public class MergeSort
{
    public static void sort(ArrayList<? extends Comparable> list)
    {
        mergesort(list, 0, list.size() - 1);
    }

    private static void mergesort(ArrayList<? extends Comparable> list, int start, int end)
    {
        if (start >= end)
            return;

        int mid = (start + end) / 2;
        mergesort(list, start, mid);
        mergesort(list, mid + 1, end);
        merge(list, start, mid, end);
    }

    private static void merge(ArrayList<? extends Comparable> list, int start, int mid, int end)
    {
        ArrayList<? extends Comparable> temp = new ArrayList<Comparable>(end - start + 1);
        int j = mid + 1;
        for (int i = start; i <= mid; i++)
        {
            while (j <= end && list.get(i).compareTo(list.get(j)) > 0)
            {
                temp.add(list.get(j));
                j++;
            }
            temp.add(list.get(i));
        }
        while (j <= end)
        {
            temp.add(list.get(j));
            j++;
        }

        int j = 0;
        for (int i = start; i <= end; i++)
        {
            list.set(i, temp.get(j));
            j++;
        }
    }

}

问题是我无法向“temp”数组添加元素,编译器说我应该将temp更改为Comparable,但是我不能将元素从“temp”替换为“list”。 我知道编译器认为列表可能是Integers和temp Floats。如何将“temp”设置为与“list”相同的类型?

2 个答案:

答案 0 :(得分:1)

使用泛型类型参数:

public static <T extends Comparable<T>> void sort(List<T> list) {
    mergesort(list, 0, list.size() - 1);
}

private static <T extends Comparable<T>> void mergesort(List<T> list, int start, int end) {
...

private static <T extends Comparable<T>> void merge(List<T> list, int start, int mid, int end) {
    ArrayList<T> temp = new ArrayList<T>(end - start + 1);
...

修改

为了获得最大的灵活性,您可以将<T extends Comparable<T>>替换为<T extends Comparable<? super T>>

例如,这将允许传递类Foo的元素列表,Foo实现Comparable<Object>。此外,您的功能与评论中建议的Collections.sort具有相同的签名。

答案 1 :(得分:-2)

您可以声明所有列表:ArrayList<Comparable>。编译器不会再抱怨了,并且可以按照您的意图工作。

然后,你有两次宣布int j。 :)