不能将数组和比较器作为通用类型传递
Can't pass array and comparator as generic types
我对泛型类型有点陌生,希望得到一些说明。在我的Java教科书中,为我们提供了一个mergesort的程序:
import java.util.Comparator;
public class mergeSortBook{
public static<K>void merge(K[] S1,K[] S2,K[] S,Comparator<K>comp){
int i=0,j=0;
while(i+j<S.length) {
if(j==S2.length || (i<S1.length && comp.compare(S1[i],S2[j])<0))
S[i+j]=S1[i++];
else
S[i+j]=S2[j++];
}
}
public static<K>void mergeSort(K[] S,Comparator<K>comp){
int n=S.length;
if (n<2) return;
int mid = n/2;
K[] S1 = Arrays.copyOfRange(S, 0, mid);
K[] S2 = Arrays.copyOfRange(S, mid, n);
mergeSort(S1,comp);
mergeSort(S2,comp);
merge(S1,S2,S,comp);
}
}
我正在尝试实现上述算法。经过一些研究,我决定实例化一个默认比较器并将其传递给 mergeSort() 函数。但是,我 运行 在尝试传入数组时遇到问题。我的 Eclipse IDE 中的错误是 The method mergeSort(K[], Comparator<K>) in the type mergeSortBook is not applicable for the arguments (int[],mergeSortBook.DefaultComparator<Integer>)
下面是我的主要方法和 DefaultComparator 方法的代码。我真的很感激任何关于传递正确类型的参数以使程序运行的提示。
public class DefaultComparator<E> implements Comparator<E>
{
@Override
public int compare(E a, E b) throws ClassCastException {
return ((Comparable<E>) a).compareTo(b);
}
}
public static void main(String args[]) {
int arr[] = {3,1,6,2,4,8,9,2,1};
mergeSort(arr,new DefaultComparator<Integer>());
}
您无法使用通用方法对 int[]
进行排序。只有引用类型适用于泛型,例如Integer[]
:
Integer arr[] = {3,1,6,2,4,8,9,2,1};
mergeSort(arr,new DefaultComparator<Integer>());
您需要 Integer
才能使用泛型方法(int
是原始类型,而不是 Comparable
)。您也可以使用 Comparator.naturalOrder()
。喜欢,
public static void main(String args[]) {
Integer[] arr = { 3, 1, 6, 2, 4, 8, 9, 2, 1 };
mergeSort(arr, Comparator.naturalOrder());
System.out.println(Arrays.toString(arr));
}
产出
[1, 1, 2, 2, 3, 4, 6, 8, 9]
最后,"correct" 类型将是 Comparator<? super K>
,而不是 Comparator<K>
。并且不要仅仅因为它是合法的就省略大括号。 S1
、S2
和 S
并不是特别有意义(或有用)的变量名。他们不遵循看起来像类型的 Java 命名约定。我们可以做得更好并且仍然使用短名称。喜欢,
public static <K> void merge(K[] left, K[] right, K[] arr, Comparator<? super K> comp) {
int i = 0, j = 0;
while (i + j < arr.length) {
if (j == right.length || (i<left.length && comp.compare(left[i], right[j])<0)) {
arr[i + j] = left[i++];
} else {
arr[i + j] = right[j++];
}
}
}
如果您打算将声明放在一行中请保持一致。喜欢,
public static <K> void mergeSort(K[] arr, Comparator<? super K> comp) {
int n = arr.length, mid = n / 2;
if (n < 2) {
return;
}
K[] left = Arrays.copyOfRange(arr, 0, mid), right = Arrays.copyOfRange(arr, mid, n);
mergeSort(left, comp);
mergeSort(right, comp);
merge(left, right, arr, comp);
}
我对泛型类型有点陌生,希望得到一些说明。在我的Java教科书中,为我们提供了一个mergesort的程序:
import java.util.Comparator;
public class mergeSortBook{
public static<K>void merge(K[] S1,K[] S2,K[] S,Comparator<K>comp){
int i=0,j=0;
while(i+j<S.length) {
if(j==S2.length || (i<S1.length && comp.compare(S1[i],S2[j])<0))
S[i+j]=S1[i++];
else
S[i+j]=S2[j++];
}
}
public static<K>void mergeSort(K[] S,Comparator<K>comp){
int n=S.length;
if (n<2) return;
int mid = n/2;
K[] S1 = Arrays.copyOfRange(S, 0, mid);
K[] S2 = Arrays.copyOfRange(S, mid, n);
mergeSort(S1,comp);
mergeSort(S2,comp);
merge(S1,S2,S,comp);
}
}
我正在尝试实现上述算法。经过一些研究,我决定实例化一个默认比较器并将其传递给 mergeSort() 函数。但是,我 运行 在尝试传入数组时遇到问题。我的 Eclipse IDE 中的错误是 The method mergeSort(K[], Comparator<K>) in the type mergeSortBook is not applicable for the arguments (int[],mergeSortBook.DefaultComparator<Integer>)
下面是我的主要方法和 DefaultComparator 方法的代码。我真的很感激任何关于传递正确类型的参数以使程序运行的提示。
public class DefaultComparator<E> implements Comparator<E>
{
@Override
public int compare(E a, E b) throws ClassCastException {
return ((Comparable<E>) a).compareTo(b);
}
}
public static void main(String args[]) {
int arr[] = {3,1,6,2,4,8,9,2,1};
mergeSort(arr,new DefaultComparator<Integer>());
}
您无法使用通用方法对 int[]
进行排序。只有引用类型适用于泛型,例如Integer[]
:
Integer arr[] = {3,1,6,2,4,8,9,2,1};
mergeSort(arr,new DefaultComparator<Integer>());
您需要 Integer
才能使用泛型方法(int
是原始类型,而不是 Comparable
)。您也可以使用 Comparator.naturalOrder()
。喜欢,
public static void main(String args[]) {
Integer[] arr = { 3, 1, 6, 2, 4, 8, 9, 2, 1 };
mergeSort(arr, Comparator.naturalOrder());
System.out.println(Arrays.toString(arr));
}
产出
[1, 1, 2, 2, 3, 4, 6, 8, 9]
最后,"correct" 类型将是 Comparator<? super K>
,而不是 Comparator<K>
。并且不要仅仅因为它是合法的就省略大括号。 S1
、S2
和 S
并不是特别有意义(或有用)的变量名。他们不遵循看起来像类型的 Java 命名约定。我们可以做得更好并且仍然使用短名称。喜欢,
public static <K> void merge(K[] left, K[] right, K[] arr, Comparator<? super K> comp) {
int i = 0, j = 0;
while (i + j < arr.length) {
if (j == right.length || (i<left.length && comp.compare(left[i], right[j])<0)) {
arr[i + j] = left[i++];
} else {
arr[i + j] = right[j++];
}
}
}
如果您打算将声明放在一行中请保持一致。喜欢,
public static <K> void mergeSort(K[] arr, Comparator<? super K> comp) {
int n = arr.length, mid = n / 2;
if (n < 2) {
return;
}
K[] left = Arrays.copyOfRange(arr, 0, mid), right = Arrays.copyOfRange(arr, mid, n);
mergeSort(left, comp);
mergeSort(right, comp);
merge(left, right, arr, comp);
}