我正在努力为一组对象制作二进制搜索工作的比较器。本质上,我们的目标是搜索一个参差不齐的数组,以找到项目的第一个匹配项或最接近的匹配项,以提供插入点。该方法传入一个泛型(这是不可更改的 - 因为这是作业)但你不能创建泛型类型的数组...所以,我的比较器抛出一个错误:“方法binarySearch(Object [],Object)in类型数组不适用于参数(Object [],E,Comparator)“。也许我需要投射通用元素“item”?我不确定。代码:
private Location findFirst(E item) {
Location current;
int closestMatchArray1;
int closestMatchArray2;
Object[] firstItemInArray2 = new Object[numArrayInUse];
Object firstItem;
Comparator<E> comparator = new CompareElement();
for (int i - 0; i < numArrayInUse; i++) {
firstItem = topArray[i];
firstItemInArray2[i] = firstItem;
}
closestMatchArray1 = Arrays.binarySearch(firstItemInArray2, item, comparator);
中学,但相关问题。在比较器中,我试图调用Comparable方法“compareTo”来获得一个负整数,给出一个项目在失败搜索时在数组中的位置的大致位置,但同样,我遇到了麻烦使用泛型,得到此错误:“方法compareTo(E)未定义为类型E”。代码:
public class CompareElement implements Comparator<E> {
public int compare(E firstItem, E secondItem) {
return firstItem.compareTo(secondItem);
}
}
答案 0 :(得分:1)
我认为您需要Comparator<Object>
或者您需要一个E[]
数组。对于后者,我建议查看这两篇文章:
鼓励以上阅读。
假设item永远不为null
根据我在上述帖子中所读到的内容,如果您知道项目永远不会是null
,您可以尝试这样的事情......
@SuppressWarnings("unchecked")
private Location findFirst(E item) {
Location current;
int closestMatchArray1;
int closestMatchArray2;
// Object[] firstItemInArray2 = new Object[numArrayInUse];
// Object firstItem;
E[] firstItemInArray2
= (E[]) Array.newInstance(item.getClass(), numArrayInUse);
E firstItem;
Comparator<E> comparator = new CompareElement();
for (int i = 0; i < numArrayInUse; i++) {
firstItem = (E) topArray[i];
firstItemInArray2[i] = firstItem;
}
closestMatchArray1 = Arrays.binarySearch(firstItemInArray2, item, comparator);
需要Class参数
如果您无法保证该项永远不会null
,并且您无法对null
值进行任何特殊处理,则可以强制通过Class<?>
参数在,如下......
@SuppressWarnings("unchecked")
private Location findFirst(E item, Class<E> clazz) {
Location current;
int closestMatchArray1;
int closestMatchArray2;
// Object[] firstItemInArray2 = new Object[numArrayInUse];
// Object firstItem;
E[] firstItemInArray2
= (E[]) Array.newInstance(clazz, numArrayInUse);
E firstItem;
Comparator<E> comparator = new CompareElement();
for (int i = 0; i < numArrayInUse; i++) {
firstItem = (E) topArray[i];
firstItemInArray2[i] = firstItem;
}
closestMatchArray1 = Arrays.binarySearch(firstItemInArray2, item, comparator);
丑陋,但它有效
或者你可以创建一个Comparator<Object>
来包装现有的Comparator<E>
,如下所示(我认为这有点像黑客,但它对我来说一直都有效)......
private Location findFirst(E item) {
Location current;
int closestMatchArray1;
int closestMatchArray2;
Object[] firstItemInArray2 = new Object[numArrayInUse];
Object firstItem;
// Comparator<E> comparator = new CompareElement();
Comparator<Object> comparator = new Comparator<Object>() {
private final Comparator<E> delegate = new CompareElement();
@Override
@SuppressWarnings("unchecked")
public int compare(Object o1, Object o2) {
return delegate.compare((E) o1, (E) o2);
}
};
for (int i = 0; i < numArrayInUse; i++) {
firstItem = topArray[i];
firstItemInArray2[i] = firstItem;
}
closestMatchArray1 = Arrays.binarySearch(firstItemInArray2, item, comparator);
希望这有帮助!
答案 1 :(得分:0)
您没有声明<E>
。您必须按如下方式定义CompareElement
:
public class CompareElement<E extends Comparable> implements Comparator<E> {
public int compare(E firstItem, E secondItem) {
return firstItem.compareTo(secondItem);
}
}
然后声明如下:
Comparator<?> comparator = new CompareElement<?>();
?
应该是您要比较的类型。
答案 2 :(得分:0)
您的E
在哪里宣布?看起来像某个类型参数在一些我们看不到的封闭类中声明。您的CompareElement
类似乎是一个比较器,它根据元素的自然顺序(即根据Comparable
)来比较元素。如果是这样,那么E
必须有一个绑定,以保证它能够与自身进行比较,<E extends Comparable<? super E>>
。您可以更改声明E
的边界,或者,如果您想像其他人建议的那样更改,将CompareElement
与封闭类分开参数化,您可以这样做:
public class CompareElement<E extends Comparable<? super E>> implements Comparator<E> {
public int compare(E firstItem, E secondItem) {
return firstItem.compareTo(secondItem);
}
}
您的第一个错误是因为您尝试使用的binarySearch
版本(带有比较器的版本)对参数类型有限制。声明如下:static <T> int binarySearch(T[] a, T key, Comparator<? super T> c)
。因此,如果您有Comparator<E>
,则需要E[]
作为第一个参数,而您需要Object[]
。你必须想出一些方法来E[]
。
但实际上对你来说,你要做的就是根本不需要使用比较器。有一个版本的binarySearch
方法没有比较器,它已经使用它们的自然顺序比较了元素。
答案 3 :(得分:-1)
您必须传递Class<E>
才能实例化E
数组。 (在运行时删除<E>
,E只是对象。)
Class<E> klazz;
E[] firstItemInArray2 = (E[])
java.lang.reflect.Arrays.newInstance(klazz, numArraysInUse);