我正在尝试制作一个处理(可比)元素排序列表的函数。因此,我使用通用
public static <T extends List<? extends Comparable>> T intersect (T A, T B) {
T C = (T) A.getClass().newInstance();
int posA = 0;
int posB = 0;
while(posA<A.size()&&posB<B.size()) {
if (A.get(posA).compareTo(B.get(posB))>0) posB++;
else if (A.get(posA).compareTo(B.get(posB))<0) posA++;
else if (A.get(posA).equals(B.get(posB))) {
C.add((Comparable)(A.get(posA)));
posA++; posB++;
}
}
return C;
}
我应该如何告诉编译器
A. get(posA)
是有效类型?扩展可比
?显然强制转换不起作用,我希望例程接受并返回任意可比对象的列表(整数、字符串、自定义对象等)
这是一个典型的泛型问题。
您是说您接受扩展可比的每个对象列表。
因此,如果另一个方法将列表传递给您的方法,这将是非常好的。
当然,不应该允许您在代码中将数字添加到该列表中,即使它会扩展可比!
您可以通过向方法签名中添加另一个泛型参数(而不是“?”)来修复代码中的此问题。然后可以在代码中强制转换到该参数。
难道您没有注意到代码中的所有不安全类型语句,其中包括多个不安全强制转换吗<你真的有很多。这通常意味着总体方法并不正确。
事实上,如果您了解泛型如何在Java中工作,事情就不会那么复杂了
这可以帮助您:
根据您的实际代码,以下是您应该考虑的主要事项:1)不要使用原始类型,例如<代码>列表
通过遵循这些想法,您可以编写如下代码:
public static <T extends Comparable<T>> List<T> intersect (List<T> A, List<T> B) {
List<T> list = new ArrayList<>();
int posA = 0;
int posB = 0;
while(posA<A.size()&&posB<B.size()) {
if (A.get(posA).compareTo(B.get(posB))>0) posB++;
else if (A.get(posA).compareTo(B.get(posB))<0) posA++;
else if (A.get(posA).equals(B.get(posB))) {
list.add(A.get(posA));
posA++; posB++;
}
}
return list;
}
这是我最初的方法,但这里的问题是,并非所有两个非ArrayList列表的交集都是ArrayList。
如果您为参数声明List
,则在编译时不会知道List的类型。因此,您将不可避免地以不安全的强制转换结束。
例如:
@SuppressWarnings("unchecked")
public static <T extends Comparable<T>, L extends List<T>> L intersect(L A, L B) {
if (A.getClass() != B.getClass()) {
throw new IllegalArgumentException("not same type between ...");
}
List<T> list = A.getClass()
.newInstance(); // uncheck
int posA = 0;
int posB = 0;
while (posA < A.size() && posB < B.size()) {
if (A.get(posA)
.compareTo(B.get(posB)) > 0)
posB++;
else if (A.get(posA)
.compareTo(B.get(posB)) < 0)
posA++;
else if (A.get(posA)
.equals(B.get(posB))) {
list.add(A.get(posA));
posA++;
posB++;
}
}
return (L) list; // uncheck
}
当试图将一个对象强制转换为与其实际类型不兼容的类型时,会抛出 ClassCastException 异常。 问题代码如下:
问题内容: 是否可以在String方法中使用默认参数。代码如下所示: 上面的代码生成错误。有可能纠正吗? 问题答案: 不,您通常这样做的方法是重载这样的方法:
这样可以采用类型或类型(但是,我不希望的类型可能是或或在我的程序中没有意义的东西)。 这可能吗?
可以使用泛型将返回类型与参数类型匹配吗? 实例案例: 我有一个抽象类,可以从不同的POJO导入数据,这个类包含一个abstract方法importData。 importData返回的对象必须与传递给该方法的对象类型相同。 由于抽象方法的每个实现的对象类型不同,并且类型不扩展另一个,如何定义抽象方法,以便实现返回类型和传递类型必须匹配? 经过考验: 结果: 方法的返回类型不必与传递的对象类型匹配。
问题内容: 有人可以解释一下这是什么意思吗? 这似乎是一个循环定义,至少可以说让我感到困惑。 问题答案: Java Generics FAQ中 有很好的解释。 从末尾开始: 概括起来,声明可以解密为:是仅可为其子类型实例化的泛型类型,并且这些子类型将继承一些有用的方法,其中一些方法具有子类型特定的参数(否则取决于子类型)。 (尽管我确实很同情-递归的泛型声明很痛苦。但是,我的协议缓冲端口到C#的情
问题内容: 是否可以在Gradle中声明一个可在Java中使用的变量?基本上,我想在build.gradle中声明一些var,然后在构建时(显然)获取它。就像C / C ++中的预处理器宏一样… 一个声明的例子就是这样: 有没有办法做这样的事情? 问题答案: 生成Java常量 你可以使用 产生Android资源 你可以使用或以通常的方式访问它们