Java中的递归枚举
我仍然有一个关于枚举的问题。这是形势的简要说明。 我有一个类背包,它有一个Hashmap内容,其中key是long类型的变量,value是带有Items的ArrayList。 我必须编写一个枚举来迭代背包的内容。但这里有一个陷阱:在一个背包里,也可以有另一个背包。枚举还应该能够遍历背包中的背包内容。(我希望你能理解,我不太擅长解释……) 以下是我的代码:Java中的递归枚举,java,enumeration,Java,Enumeration,我仍然有一个关于枚举的问题。这是形势的简要说明。 我有一个类背包,它有一个Hashmap内容,其中key是long类型的变量,value是带有Items的ArrayList。 我必须编写一个枚举来迭代背包的内容。但这里有一个陷阱:在一个背包里,也可以有另一个背包。枚举还应该能够遍历背包中的背包内容。(我希望你能理解,我不太擅长解释……) 以下是我的代码: public Enumeration<Object> getEnumeration() { return new Enum
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++]);
}
}
}
};
公共枚举getEnumeration(){
返回新枚举(){
私有int itemsDone=0;
//我用HashMap的所有值创建了一个新数组,这样我就可以使用
//他们在nextElement()中
Collection keysCollection=getContent().keySet();
Long[]keys=keysCollection.toArray(新的Long[keysCollection.size());
公共布尔值hasMoreElements(){
if(itemsDone
这段代码能正常工作吗?我担心的只是“return temporaryList.get(i).getEnumeration();”。用户是否仍能像平常一样只使用hasMoreElemens()和nextElement()呢
感谢您的帮助
Harm De Weirdt如果是出于实际目的而不是家庭作业,我会使用接口而不是旧的接口。对于迭代器,您有一些 其次,您的解决方案似乎有一个bug。方法nextElement()应该返回元素本身,但行返回temporaryList.get(i).getEnumeration()会返回枚举对象 --编辑-- Polygene建议了一个很好的、优雅的解决方案。我想到了其他一些东西。您可以实现一个通用的ChainEnumeration类(implements Enumeration),它接收枚举列表并允许枚举基础项。在树结构中,返回一个简单的枚举,其中一个项用于叶,一个链枚举用于内部节点
ChainEnumeration的实现很简单:它管理一个迭代器列表,加上对当前活动迭代器的引用,从中提取项目。您需要创建一个
堆栈
。当您看到另一个背包
时,您将该元素上的新枚举
推到堆栈中。您总是从堆栈顶部执行nextElement()
。如果顶部元素为空,则将其弹出。重复此操作直到stack.isEmpty()
另一种可能更简单的技术(取决于您对递归的熟悉程度)是使用“内部”枚举,它本身可以有内部枚举。下面是一个使用迭代器对对象[]
进行迭代的代码示例。它递归地迭代到任何嵌套的对象[]
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();
}
}
这就是我问题的重点。我需要找到一种方法,这样我可以在背包中迭代可能的背包。所以这段代码不会这样做?你能建议一种方法让它工作吗?@Harm De Weirdt:请看我在回复中添加的文本。我希望它能有所帮助。你说的“接收枚举列表”是什么意思。我从哪里获得该列表的枚举数?因为我一次只能获得一个额外的枚举数,而且只有当我在原始迭代器中遇到一个背包时才能获得。我应该如何构造树结构?将我的第一个背包用作节点,将底层背包用作叶?这就是你的意思吗?1)首先我创建一个新堆栈。2)当我遇到ba时ckpack,我做stack.push(backack.getEnumeration())这里是我不能完全理解的地方。我想前面的事情都是在nextElement()方法中完成的?但是,那些已经迭代过的对象和那些还没有被迭代过的对象是如何“保存”的呢你能提供一点示例代码吗?我现在真的无法一步一步地了解程序的工作方式。@哈姆:我提供了一个不同技术的代码示例,使用内部迭代器,实现起来更简单。非常感谢这个示例,我将尝试进行调整,使其与枚举一起工作:DI'm back,我成功地让代码工作。(我想,我在我的项目中测试了它,它做了它必须做的事情),但没有真正了解hasMoreElements()是如何工作的(对于使用HashMap的枚举,我放置了以下内容:如果有一个内部枚举并且它有更多的元素,则为True;如果我们已到达此HashMap的末尾,则为false;或者如果ArrayList中至少有一个元素,则为false。但我认为这并不能描述整个方法,是吗?@Harm:我认为您可以隐藏递归enumera的内部工作如果存在nextElement()
,则返回true
,并且它不会抛出NoSuchElementException
。在内部,是的,递归枚举具有下一个元素,如果(i)有一个具有下一个元素的内部元素,或者(ii)在该级别有下一个“正常”元素。
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)