前几天我正在编写一个程序,要求我:在ArrayList<String>
内获取特定对象的频率,删除所有出现的给定项目等,而不是{{{ 1}}接口。我决定编写自己的帮助类,并希望尽可能地使它成为可重用的。我决定将List
指定为集合的参数类型,因此我可以将它用于实现List
接口的任何类。但是这些类通常使用泛型来定义,我不知道要删除的项的类类型。因此,我必须一般性地定义静态辅助方法,因为静态类不能显式包含泛型类型,或者将要删除的对象的类类型定义为List
。我以两种方式实现它,见下文,但我想知道使用一个是否有任何好处。
关于该主题的一些进一步的问题:
Object
仍然有效。 使用Object类类型
实现ListTools_V2.getFrequencyOf(ArrayList<String> items, String s)
使用泛型实现
import java.util.List;
/** General utility class for performing frequently needed operations
on any class implementing the List interface **/
public class ListTools {
public static void removeAllOccurrences(List items, Object o) {
while(items.contains(o)) {
items.remove(o);
}
}
public static int getFrequencyOf(List items, Object o) {
int frequency = 0;
for(Object item : items) {
if(item.equals(o)) {
frequency++;
}
}
return frequency;
}
}
答案 0 :(得分:1)
两个操作都在给定对象引用和列表中的元素之间进行相等(o
)操作,并且相等不限于相同类型的对象,因此不应限制List
与列表的类型参数的类型相同。
但是,原始类型不好,因此不应使用原始类型public static void removeAllOccurrences(List<?> items, Object o)
public static int getFrequencyOf(List<?> items, Object o)
。当不需要针对任何事物约束类型变量时,您应该使用通配符对其进行参数化:
var text = "1\n2\n3\n4\n5";
答案 1 :(得分:0)
Generic更好,因为它在编译时检测到类型相关的问题。
在运行期间&#34;擦除&#34;发生了,没有&#34;意思&#34;对仿制药。
例如:
List apples = new ArrayList();
apples.add(new Apple());
apples.add(new Mango()); //compiles, but this is wrong
apples.add(new Chair()); //compiles, but this is wrong
你当然必须意识到各种各样的陷阱&#34;通用机制。
我可以轻易想到的例子是:
List<Mango>
未展开List<Fruit>
,因此您应使用List<? super Fruit>
或List<? extends Fruit>
你做不了类似的事情:
T.getClassName()
答案 2 :(得分:0)
泛型是实现此类的推荐方法。它们可用于向您的用户(使用此类的任何人)提供一些隐含信息。 例如:
List<Cat> cats = ...;
ListTools.removeAllOccurrences(cats, new Dog());
它没有意义,因为在猫列表中不能有任何狗。但是用户可以执行此代码并想象他已从cat的列表中删除了一些狗。另一方面,通用版本通知用户这个不适当的呼叫。
List<Cat> cats = ...;
ListTools_V2.removeAllOccurrences(cats, new Dog()); // Compile time error because it is pointless
此外,还有性能提升。如果猫的名单包含数以千计的猫,你真的想在大量的猫咪名单中搜索那只狗吗? (包含方法实际上搜索整个List)或者你只是想在编译时避免它? ;)
答案 3 :(得分:0)
你的getFrequencyOf()方法体在两种情况下基本相同,除了在一种情况下你传递原始List而在另一种情况下你将它参数化为接受任何类型。
1 -
public static int getFrequencyOf(List items, Object o) {
int frequency = 0;
for(Object item : items) {
if(item.equals(o)) {
frequency++;
}
}
return frequency;
}
此处列表是原始类型。对泛型类型List的引用应该参数化,而不是。但它适用于任何类型的List(整数,长整数,字符串等)
2 -
public static <E> int getFrequencyOf(List<E> items,E o) {
int frequency = 0;
for(E item : items) {
if(item.equals(o)) {
frequency++;
}
}
return frequency;
}
此处列表不是原始类型。对泛型类型List的引用应该参数化,它是。这也适用于任何类型的List(整数,长整数,字符串等)