Java中的递归枚举

Java中的递归枚举,java,enumeration,Java,Enumeration,我仍然有一个关于枚举的问题。这是形势的简要说明。 我有一个类背包,它有一个Hashmap内容,其中key是long类型的变量,value是带有Items的ArrayList。 我必须编写一个枚举来迭代背包的内容。但这里有一个陷阱:在一个背包里,也可以有另一个背包。枚举还应该能够遍历背包中的背包内容。(我希望你能理解,我不太擅长解释……) 以下是我的代码: public Enumeration<Object> getEnumeration() { return new Enum

我仍然有一个关于枚举的问题。这是形势的简要说明。 我有一个类背包,它有一个Hashmap内容,其中key是long类型的变量,value是带有Items的ArrayList。 我必须编写一个枚举来迭代背包的内容。但这里有一个陷阱:在一个背包里,也可以有另一个背包。枚举还应该能够遍历背包中的背包内容。(我希望你能理解,我不太擅长解释……)

以下是我的代码:

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)