首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何避免在泛型递归迭代器中出现未经检查的强制转换警告?

如何避免在泛型递归迭代器中出现未经检查的强制转换警告?
EN

Code Review用户
提问于 2011-06-26 20:54:51
回答 2查看 40.1K关注 0票数 11

Java的集合框架没有用于递归数据结构的迭代器,这有点奇怪。因为我需要这样的东西,所以我自己写的。首先,我需要递归元素:

代码语言:javascript
复制
public interface RecursiveElement<T>
{
    public Iterator<T> getChildrenIterator();
}

然后是一个Iterator

代码语言:javascript
复制
public class RecursiveIterator<T> implements Iterator<T>
{
    private Deque<Iterator<T>> stack;
    private Iterator<T> currentStackItem;

    /**
     * Creates a new instance
     * 
     * @param root
     *            all children of this node are iterated. The root node itself
     *            is not returned
     * @throws NullPointerException
     *             if root is null
     */
    public RecursiveIterator(final RecursiveElement<T> root)
    {
        if (root == null)
            throw new NullPointerException(
                    "root argument to this iterator must not be null");
        stack = new LinkedList<Iterator<T>>();
        currentStackItem = root.getChildrenIterator();
    }

    @Override
    public boolean hasNext()
    {
        return currentStackItem != null;
    }

    @Override
    public T next()
    {
        final T result = currentStackItem.next();
        if (result instanceof RecursiveElement)
        {
            stack.addLast(currentStackItem);
             // Here is the warning:
            currentStackItem = ((RecursiveElement<T>)result).getChildrenIterator();
        }
        while (currentStackItem != null && !currentStackItem.hasNext())
            currentStackItem = stack.pollLast();
        return result;
    }

    @Override
    public void remove()
    {
        currentStackItem.remove();
    }
}

该代码运行得很好,但是我在标记的行中从next()方法的编译器那里得到了警告。我很清楚为什么会出现这种警告,但我没有想出任何解决方案,说明如何在没有此警告的情况下解决问题(除了抑制警告外)。有什么想法吗?

EN

回答 2

Code Review用户

回答已采纳

发布于 2011-06-27 07:17:47

我觉得你对此无能为力。您必须在这里进行强制转换,在此过程中,您将丢失有关类型参数的所有信息:编译器不能知道,如果您有一个RecursiveElement,它总是一个RecursiveElement<T>,并且“谢谢”类型擦除--它不能检查运行时类型。

票数 7
EN

Code Review用户

发布于 2014-04-16 16:02:32

类型检查器在这里标记了一个真正的问题。要可视化这一点,请将您的RecursiveElement<T>替换为通用Iterable<T>,它提供相同的类型保证。

当不同的层混合不同的类型时,RecursiveIterator不幸地崩溃了。下面是一个示例:

代码语言:javascript
复制
public class Main {
  public static void main(String[] args) {
    final RecursiveIterator<IntElem> itr = new RecursiveIterator<IntElem>(new MixedRecursiveElem());
    while ( itr.hasNext() ) {
      IntElem elm = itr.next();
    }
  }
}

class IntElem implements RecursiveElement<Integer> {
  public Iterator<Integer> getChildrenIterator() {
    return Arrays.asList(1, 2, 3).iterator();
  }
}

class MixedRecursiveElem implements RecursiveElement<IntElem> {
  public Iterator<IntElem> getChildrenIterator() {
    return Arrays.asList(new IntElem(), new IntElem()).iterator();
  }
}

Output:
Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to IntElem
    at Main.main(Main.java:7)

你的选择是:

  • 试着把递归的责任推到你的实际元素上;
  • 尝试一些技巧,通过添加类型变量来接受有限数量的递归;
  • 删除类型安全性并在过滤迭代器中包装。
票数 3
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/3130

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档