构建自定义迭代器

时间:2011-03-06 22:48:49

标签: java iterator hashmap

我正在制作这个类,它是一个基于哈希映射的自定义Map。我有一个add方法,如果添加一个对象,该对象将成为键,如果该对象当前不在列表中,则其值将为1。但是,如果添加当前在列表中的对象,其值将增加1.因此,如果我添加了10个相同的字符串,则键将是该字符串,值将为10.我在实践中理解我遍历地图,实际上只有一个对象要迭代,但是,我试图创建一个内部类,它将定义一个迭代器,它会迭代同一个对象,但是它的值很多倍。我可以通过简单地使用for循环来构造一个合适的ArrayList并为此创建一个迭代器,但这样做效率太低了。有没有一种简单或更有效的方法来做到这一点?

4 个答案:

答案 0 :(得分:1)

您可以使用两个变量:

private T nextObj = null;
private int times = 0;

T next(){
    if(times==0){
        // get the next object and set the times variable to it's value in the hashmap
    }
    times--;
    return nextObj;   
}

答案 1 :(得分:0)

您可以使用集合API中的nCopies。这将创建一个只有一个引用的列表,因此它将是高效的。然后返回List迭代器。无需创建内部类。

假设您的Map<String, Integer>实例变量名为map,您可以执行以下操作:

Iterator<String> customIteratorForKey(String key) {
    return Collections.nCopies(map.get(key), key).iterator();
}

答案 2 :(得分:0)

听起来你正在实现一个multiset or bag:一个计算每个唯一元素的集合。由于这是一个学校项目,我将提供一些指示,说明如何做而不是提供代码。试试你的运气,如果你遇到困难,请改进你的问题。

当我创建一个使用其后面的另一个集合的新集合类型时,我通常在构建迭代器时做同样的事情。

  1. Bag.Iterator的构造函数将使用Map中的迭代器初始化自己。
  2. 正如dtech所示,迭代器需要跟踪它正在计算的当前对象以及它应该返回它的次数。
  3. next()需要在开始时获取下一个对象,并且当前对象耗尽计数。
  4. hasNext()必须做同样的事情,而不是实际减少计数或抓住下一个对象。

答案 3 :(得分:0)

我终于明白了。这是我的解决方案。感谢所有回复并给我指点的人。

    private int times = 0;
    private boolean flag = true;

    Iterator<Entry<T, Integer>> it = Bag.entrySet().iterator();
    private Entry<T, Integer> t = it.next();
    private int value = t.getValue();
    private T nextObj = t.getKey();

    public boolean hasNext() {
        if (times > 0) {
            return true;
        }
        return it.hasNext();
    }


    public T next() {
        if (this.hasNext() == false) {
            throw new NoSuchElementException();
        }
        if (times == 0 && flag == true) {
            times = value;
            flag = false;
        }
        if (times == 0 && flag == false) {
            t = it.next();
            value = t.getValue();
            nextObj = t.getKey();
            times = value;
        }
        times--;
        return nextObj;
    }