【问题标题】:Building a custom iterator构建自定义迭代器
【发布时间】:2011-03-06 22:48:49
【问题描述】:

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

【问题讨论】:

    标签: java iterator hashmap


    【解决方案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;   
    }
    

    【讨论】:

    • 我看不出你对 nextObj 做了什么。你能解释一下这个变量吗?
    • 它只是对您的迭代器要返回的下一个对象的引用。因此,不要说“return something”,而是说“nextObj = something”。如果您还没有构建自己的迭代器,您可以定义一个并使用 Map 的迭代器的 next() 来填充 nextObj。
    【解决方案2】:

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

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

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

    【讨论】:

    • 我实际上必须使用一个扩展迭代器的内部类,因为这是一个学校项目:/
    【解决方案3】:

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

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

    1. Bag.Iterator 的构造函数将使用来自 Map 的迭代器对其自身进行初始化。
    2. 如 dtech 上面所示,迭代器需要跟踪它正在计数的当前对象以及它应该返回它的次数。
    3. next() 需要在开始时获取下一个对象,并且一旦当前对象的计数用完。
    4. hasNext() 必须在不实际减少计数或抓取下一个对象的情况下执行相同的操作。

    【讨论】:

      【解决方案4】:

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

          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;
          }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-08-23
        • 2015-02-04
        • 2011-07-09
        • 2017-08-25
        • 2013-02-17
        • 2015-11-19
        • 2013-09-02
        相关资源
        最近更新 更多