如何在Java中将不同数据类型的元素插入到单个堆栈中?
答案 0 :(得分:10)
它似乎打败了generics的目的,但在这里:
Stack<Object>s = new Stack<Object>();
s.add("hello");
s.add(1); // int is autoboxed to Integer
从Object
检索Stack
时,需要花费一些精力来确定每个元素的类型 - 它需要使用instanceof
和typecasts:
while (!s.isEmpty()) {
Object e = s.pop();
if (e instanceof String)
System.out.println("String: " + (String)e);
else if (e instanceof Integer)
System.out.println("Integer: " + (Integer)e);
else
System.out.println("Other type: " + e);
}
现在,在将泛型添加到语言之前的5天内,我们有类似于Java之前的脆弱代码的东西。
答案 1 :(得分:6)
通常,您需要使用继承来解决此问题。可能使用标记界面:
interface MyMarker
{
}
class Foo implements MyMarker
{
}
class Bar implements MyMarker
{
}
接口在这种情况下很实用,因为你可以在一个类中实现无限数量的接口,并且你可以在类中的任何地方添加额外的接口。
然后你可以将Foo和Bar放在同一个堆栈中:
Stack<MyMarker> s = new Stack<MyMarker>();
s.add(new Foo());
s.add(new Bar());
如果可能的话,这是要走的路。否则你就必须像coobird所说的那样去做。
答案 2 :(得分:0)
堆栈的泛型参数应该是所有元素运行时类型的公共超类型。对于完全异构的集合,Object
是所有引用类型的常见超类型。所以:
Queue<Object> stack = Collections.asLifoQueue(new ArrayDeque<Object>());
stack.add("red");
stack.add(Color.GREEN);
stack.add(stack);
显然,当你从堆栈中弹出这些元素时,你需要进行instanceof
检查以路由到适当的代码(并且可能是强制转换)。
可能更好的是引入一层间接。而不是直接将对象放在队列中,将它们包装在有意义的对象中。 instanceof
检查都可以通过调用执行所需操作的(虚拟)方法来替换。这就是多态性的假设。