制作通用数组是不好的做法,还有什么选择呢?

MyE*_*nty 14 java sorting generics

我已经在学校用C++编写了3年的代码.我刚开始在2天前用Java编写代码; 我的问题是:

制作通用数组是不好的做法吗?会有什么选择?

我很难过,除了做一些奇怪的事情之外,我似乎无法制作一个通用数组,比如这个例子:

//Class implementing the MergeSort algorithm with generic types
// Revised by Doina January 2014

package Sorting;

import java.lang.*;

public class MergeSort {

    // Wrapper method for the real algorithm
    // T is the generic type which will be instantiated at runtime
    //  elementas are required to be comparable
    public static <T extends Comparable<T>> void sort(T[] a) {
        mergesort(a, 0, a.length - 1);
    }

    // Recursive mergesort method, following the pseudocode
    private static <T extends Comparable<T>> void mergesort(T[] a, int i, int j) {
        if (j - i < 1) return;
        int mid = (i + j) / 2;
        mergesort(a, i, mid);
        mergesort(a, mid + 1, j);
        merge(a, i, mid, j);
    }

    // Merge method
    // Here we need to allocate a new array, but Java does not allow allocating arrays of a generic type
    // As a work-around we allocate an array of type Object[] the use type casting
    // This would usually generate a warning, which is suppressed
    @SuppressWarnings("unchecked")
    private static <T extends Comparable<T>> void merge(T[] a, int p, int mid, int q) {

        Object[] tmp = new Object[q - p + 1];
        int i = p;
        int j = mid + 1;
        int k = 0;
        while (i <= mid && j <= q) {
            if (a[i].compareTo(a[j]) <= 0)
                tmp[k] = a[i++];
            else
                tmp[k] = a[j++];
            k++;
        }
        if (i <= mid && j > q) {
            while (i <= mid)
                tmp[k++] = a[i++];
        } else {
            while (j <= q)
                tmp[k++] = a[j++];
        }
        for (k = 0; k < tmp.length; k++) {
            a[k + p] = (T) (tmp[k]); // this is the line that woudl generate the warning
        }
    }

    // Main methos to test the code, using Integer Objects
    public static void main(String[] args) {
        Integer[] a = new Integer[5];
        a[0] = new Integer(2);
        a[1] = new Integer(1);
        a[2] = new Integer(4);
        a[3] = new Integer(3);
        a[4] = new Integer(-1);

        // T will be instantiated to Integer as a resutl of this call
        MergeSort.sort(a);

        // Print the result after the sorting
        for (int i = 0; i < a.length; i++)
            System.out.println(a[i].toString());
    }
}
Run Code Online (Sandbox Code Playgroud)

Mak*_*oto 21

这本身并不是一个坏主意; 只是泛型和数组不能很好地混合.

原因是协方差和不变性.数组是协变(Integer[]是的Object[],因为Integer是一个Object,但通用类是不变的(List<Integer>不是一个List<Object>即使一个IntegerObject).

你还必须处理未经检查的强制转换,这会破坏泛型的整个目的.创建通用数组的最常用方法是E[] foo = (E[]) new Object[10];- 不是类型安全的,不能在编译时强制执行.可以在运行时对其进行推理,但是那时泛型带来的编译时检查会丢失.

要直接回答这个问题,在这里和在可能的情况,您要使用Java集合来代替,因为他们发挥非常很好地与仿制药.

只是看一下你提供的代码,我想用List<T>而不是用T[]你的大部分问题来解决问题(我希望你传递一个ArrayList,因为这些操作可能会因链表而变得昂贵).