避免在排序算法中使用原始类型Comparable的正确方法是什么?

时间:2017-12-07 06:55:44

标签: java raw-types

我正在编写合并排序算法,所以我希望所有方法都采用实现Comparable接口的参数,即有一个名为compareTo的方法。

我多次被告知要避免在新代码中使用 原始类型 。但我无法找到替代它们的正确方法。      

public class Merge{
    private static Comparable[] aux;
    private Merge() {}

    private static boolean less(Comparable v,Comparable w){
        int sign=v.compareTo(w);
        if (sign==0) throw new IllegalArgumentException("Repeated points");
        return sign<0;
    }


    private static void exch(Comparable[] a,int i,int j){
        Comparable swap =a[i];
        a[i]=a[j];
        a[j]=swap;
    }

    private static void insertSort(Comparable[] a,int lo,int hi){

        for(int i=lo;i<hi+1;++i){
            for(int j=i;j>lo;--j){
                if(less(a[j],a[j-1]))
                    exch(a,j,j-1);
                else
                    break;
            }
        }
    }

    private static void merge(Comparable[] a,Comparable[] aux,int lo,int mid,int hi){
        for(int k=lo;k!=hi+1;++k){
            aux[k]=a[k];
        }

        int i=lo,j=mid+1;
        for(int k=lo;k!=hi+1;++k){
            if(i>mid){
                a[k]=aux[j++];
            }
            else if(j>hi){
                a[k]=aux[i++];
            }
            else if(less(aux[j],aux[i])){
                a[k]=aux[j++];
            }
            else{
                a[k]=aux[i++];
            }
        }
    }


    private static void sort(Comparable[] a, Comparable[] aux,int lo,int hi){
        if(hi<=lo+6){
            insertSort(a,lo,hi);
            return;
        }
        int mid=lo+ (hi-lo)/2;
        sort(a,aux,lo,mid);
        sort(a,aux,mid+1,hi);
        if(!less(a[mid+1],a[mid])) return;
        merge(a,aux,lo,mid,hi);
    }

    private static void sort(Comparable[] a){
        aux=new Comparable[a.length];
        sort(a,aux,0,a.length-1);
    }     

}  

问题What is a raw type and why shouldn't we use it?与我的不同。实际上,我之前已经读过这个问题。不过,我不知道如何避免在这里使用Comparable

1 个答案:

答案 0 :(得分:2)

如果您有Comparable,请使用T。并将T声明为<T extends Comparable<? super T>>

但是,您将面临阵列创建的问题。有两种方法可以绕过它。您可以克隆原始数组并清除它,以防您需要使用null进行初始化,或者您可以使用Reflection来创建数组。

public class Merge {
    private Merge() {
    }

    private static <T extends Comparable<? super T>> boolean less(T v, T w) {
        int sign = v.compareTo(w);
        if (sign == 0) throw new IllegalArgumentException("Repeated points");
        return sign < 0;
    }


    private static <T extends Comparable<? super T>> void exch(T[] a, int i, int j) {
        T swap = a[i];
        a[i] = a[j];
        a[j] = swap;
    }

    private static <T extends Comparable<? super T>> void insertSort(T[] a, int lo, int hi) {

        for (int i = lo; i < hi + 1; ++i) {
            for (int j = i; j > lo; --j) {
                if (less(a[j], a[j - 1]))
                    exch(a, j, j - 1);
                else
                    break;
            }
        }
    }

    private static <T extends Comparable<? super T>> void merge(T[] a, T[] aux, int lo, int mid, int hi) {
        for (int k = lo; k != hi + 1; ++k) {
            aux[k] = a[k];
        }

        int i = lo, j = mid + 1;
        for (int k = lo; k != hi + 1; ++k) {
            if (i > mid) {
                a[k] = aux[j++];
            } else if (j > hi) {
                a[k] = aux[i++];
            } else if (less(aux[j], aux[i])) {
                a[k] = aux[j++];
            } else {
                a[k] = aux[i++];
            }
        }
    }


    private static <T extends Comparable<? super T>> void sort(T[] a, T[] aux, int lo, int hi) {
        if (hi <= lo + 6) {
            insertSort(a, lo, hi);
            return;
        }
        int mid = lo + (hi - lo) / 2;
        sort(a, aux, lo, mid);
        sort(a, aux, mid + 1, hi);
        if (!less(a[mid + 1], a[mid])) return;
        merge(a, aux, lo, mid, hi);
    }

    private static <T extends Comparable<? super T>> void sort(T[] a) {
        T[] aux = a.clone();
        sort(a, aux, 0, a.length - 1);
    }

}

如果您使用方法对象,则可以取消重复类型参数<T extends Comparable<? super T>>以及重复aaux

public enum Merge {
    ;

    private static class Merger<T extends Comparable<? super T>> {
        private final T[] a;
        private final T[] aux;

        private Merger(T[] a) {
            this.a = a;
            aux = a.clone();
        }
        private boolean less(T v, T w) {
            int sign = v.compareTo(w);
            if (sign == 0) throw new IllegalArgumentException("Repeated points");
            return sign < 0;
        }

        private void exch(int i, int j) {
            T swap = a[i];
            a[i] = a[j];
            a[j] = swap;
        }

        private void insertSort(int lo, int hi) {

            for (int i = lo; i < hi + 1; ++i) {
                for (int j = i; j > lo; --j) {
                    if (less(a[j], a[j - 1]))
                        exch(j, j - 1);
                    else
                        break;
                }
            }
        }

        private void merge(int lo, int mid, int hi) {
            for (int k = lo; k != hi + 1; ++k) {
                aux[k] = a[k];
            }

            int i = lo, j = mid + 1;
            for (int k = lo; k != hi + 1; ++k) {
                if (i > mid) {
                    a[k] = aux[j++];
                } else if (j > hi) {
                    a[k] = aux[i++];
                } else if (less(aux[j], aux[i])) {
                    a[k] = aux[j++];
                } else {
                    a[k] = aux[i++];
                }
            }
        }


        private void sort(int lo, int hi) {
            if (hi <= lo + 6) {
                insertSort(lo, hi);
                return;
            }
            int mid = lo + (hi - lo) / 2;
            sort(lo, mid);
            sort(mid + 1, hi);
            if (!less(a[mid + 1], a[mid])) return;
                merge(lo, mid, hi);
        }
        private void sort() {
            sort(0, a.length - 1);
        }
    }
    public static <T extends Comparable<? super T>> void sort(T[] a) {
        new Merger<>(a).sort();
    }

}