我仍然有关于枚举的问题。这是一个情况的快速草图。 我有一个类Backpack,它有一个Hashmap内容,其键为long类型的变量,value为带有Items的ArrayList。 我必须写一个枚举,迭代背包的内容。但这里有一个问题:在背包里,还可以有另一个背包。并且Enumeration还应该能够迭代背包中的背包内容。 (我希望你能效仿,我不是很擅长解释..)
这是我的代码:
public Enumeration<Object> getEnumeration() {
return new Enumeration<Object>() {
private int itemsDone = 0;
//I make a new array with all the values of the HashMap, so I can use
//them in nextElement()
Collection<Long> keysCollection = getContent().keySet();
Long [] keys = keysCollection.toArray(new Long[keysCollection.size()]);
public boolean hasMoreElements() {
if(itemsDone < getContent().size()) {
return true;
}else {
return false;
}
}
public Object nextElement() {
ArrayList<Item> temporaryList= getContent().get(keys[itemsDone]);
for(int i = 0; i < temporaryList.size(); i++) {
if(temporaryList.get(i) instanceof Backpack) {
return temporaryList.get(i).getEnumeration();
}else {
return getContent().get(keys[itemsDone++]);
}
}
}
};
这段代码能否正常运行?它只是“return temporaryList.get(i).getEnumeration();”我对某事感到担心。用户是否仍然可以像通常那样只使用hasMoreElemens()和nextElement()?
感谢任何帮助,
Harm De Weirdt
答案 0 :(得分:2)
您需要创建Stack<Enumeration<Object>>
。当您看到另一个Backpack
时,push
会将该元素上的Enumeration
新Stack
nextElement()
。你总是从堆栈的顶部Stack.isEmpty()
。如果top元素为空,则将其弹出。重复直到Iterator
。
另一种可能更简单的技术(取决于递归的舒适程度)是使用“内部”枚举,它本身可以有内部枚举。以下是Object[]
上使用Object[]
的代码示例。它以递归方式迭代到任何嵌套的public class RecursiveIterator implements Iterator<Object> {
final Object[] arr;
int index = 0;
Iterator<Object> inner;
RecursiveIterator(Object[] arr) {
this.arr = arr;
}
@Override public boolean hasNext() {
while (true) {
if (inner != null) {
if (inner.hasNext()) {
return true;
} else {
inner = null;
index++;
}
}
if (index == arr.length) return false;
if (arr[index] instanceof Object[]) {
inner = new RecursiveIterator((Object[]) arr[index]);
} else {
return true;
}
}
}
@Override public Object next() {
if (!hasNext()) throw new NoSuchElementException();
return (inner != null) ? inner.next() : arr[index++];
}
@Override public void remove() {
throw new UnsupportedOperationException();
}
}
。
static void dump(Object[] arr) {
Iterator<Object> iter = new RecursiveIterator(arr);
while (iter.hasNext()) {
System.out.print(iter.next() + " ");
}
System.out.println("(done)");
}
public static void main(String[] args) throws FileNotFoundException {
dump(new Object[] {
1,
2,
new Object[] {
3,
new Object[] { 4 },
5,
},
6,
new Object[] {},
7,
});
dump(new Object[] {
new Object[] {},
new Object[] {
new Object[] {
new Object[] {},
},
},
new Object[] {},
new Object[] { null },
});
}
这是一个测试工具:
1 2 3 4 5 6 7 (done)
null (done)
打印:
{{1}}
答案 1 :(得分:1)
如果是出于实际目的而不是作业,我会使用Iterator界面而不是旧版Enumeration。对于迭代器,您有一些nice utilities in the apache collections project.
其次,您的解决方案似乎有一个错误。方法nextElement()应返回元素本身,但行返回temporaryList.get(i).getEnumeration()返回一个Enumeration对象。
- 编辑 -
polygenelubricants提出了一个很好的,优雅的解决方案。我想到了别的什么。您可以实现一个通用的ChainEnumeration类(实现Enumeration),它接收枚举列表并允许枚举基础项。在树结构中,返回一个简单的枚举,其中包含一个用于叶子的项目,以及一个内部节点的链枚举。
ChainEnumeration的实现很简单:它管理一个迭代器列表,以及对当前活动迭代器的引用,其中包含项目。