如何传递一个List<T>
,其中包含一些我未向方法声明的特定允许类型。
E.g。将类型限制为Integer,Boolean和String
:
// Pseudo code
public void method(List<Integer OR Boolean OR String> myList);
如果我使用List<Object>
,我可以将所有内容放入该列表中:
public void method(List<Object> myList);
如果我使用List,我可以将Parent
及其子类的所有实例放入该列表中:
public void method(List<Parent> myList);
如果我是声明那些子类(AllowedTypeA extends Parent
)的人就足够了。但是,当我不是我想要使用的类的所有者时,我该怎么办(我无法使Integer
扩展Parent
)?
答案 0 :(得分:7)
最好的办法是将这个混合列表包装成一个类,并提供方法来添加你想要允许的内容:
class WrappedMix {
private List<Object> oddsAndEnds = ...
public void add( Integer el ){ oddsAndEnds.add( el ); }
public void add( Boolean el ){ oddsAndEnds.add( el ); }
public void add( String el ){ oddsAndEnds.add( el ); }
}
或者使用合适的覆盖(和重载)扩展ArrayList,
虽然我很好奇你为什么要这样一个列表 - 它的处理并不方便。
答案 1 :(得分:2)
从概念上讲,我更喜欢@ laune的解决方案。我更喜欢类型安全和编译错误,而不是将一堆东西扔进列表并忘记添加允许的类型。
话虽这么说,它仍然可以做,虽然你必须做一些额外的东西来使这个实用,即如果你删除对象类型,你也应该删除所有与之关联的对象它需要覆盖其他方法,例如addAll
以确保正常运行。
这种方法与laune相比更加灵活,因为您可以随时添加allowedTypes。对于你的情况,可能不是最好的,但一般的问题仍然有趣,我拍了一下。也许你想要一些你的列表来存储整数,而不是其他的。您可以使用addPermittedObject
方法执行此操作。
public class SelectiveList extends ArrayList<Object> {
//the (types of) objects that we can store
private ArrayList<Object> permittedObjects = new ArrayList<Object>();
// put an Object type into the list
public boolean addPermittedObject(Object o) {
for (Object type : permittedObjects) {
if (type.getClass() == o.getClass()) {
return false; // if we already have it, do not add it again
}
}
return permittedObjects.add(o); // else let's add it
}
// remove the Object type
public boolean removePermittedObject(Object o) {
for (Object type : permittedObjects) {
if (type.getClass() == o.getClass()) {
return permittedObjects.remove(type);
}
}
return false;
}
@Override
public boolean add(Object o) {
for (Object type : permittedObjects) {
if (type.getClass() == o.getClass()) {
return super.add(o); // go ahead and add the item since it
// matches our list
}
}
return false;
}
}
并测试它:
public static void main(String[] args) {
SelectiveList selectiveList = new SelectiveList();
selectiveList.add("Potato");
selectiveList.add(1);
selectiveList.add(true);
System.out.println(selectiveList.size()); // prints 0
// these objects need to be initialized, but their contents do not
// matter
selectiveList.addPermittedObject(new String());
selectiveList.addPermittedObject(new Boolean(false));
selectiveList.addPermittedObject(new Integer(1));
selectiveList.add("Potato");
selectiveList.add(1);
selectiveList.add(true);
System.out.println(selectiveList.size()); // prints 3
}