【问题标题】:Implementing the Iterable interface实现 Iterable 接口
【发布时间】:2011-08-28 08:49:01
【问题描述】:

我刚刚在一份旧试卷中发现了这个试题,并正在为即将到来的考试做准备。我想不通:

下面描述了一个人为的部分类,它实现了 Iterable 接口。这个类的唯一目的是提供一种方法来迭代属性things.

我们需要在课堂上填写两件事来完成它。这里是类

private class PartialIterableClass /*FILL IN */ {
   private String[] things;
   public PartialIterableClass( String[] things ){
      this.things = things;
   }
   /*FILL IN 2*/
}

我猜它应该类似于:

private class PartialIterableClass implements Iterable<PrivateIterableClass> {
   private String[] things;
   public PartialIterableClass( String[] things ){
      this.things = things;
   }
   public Iterator<PartialIterableClass> iterator( ){
   return new Iterator<PartialIterableClass>( ) {

   }
   }
}

不过,我不确定如何充实这个问题的答案,有人可以帮忙吗?

【问题讨论】:

  • 如果实现了Comparable接口,不应该有compare()方法吗?
  • 您的解决方案忽略了有利于类名的问题,您应该改为实现 Comparable
  • 您阅读本文的试卷有多“旧”?我之所以问,是因为它很可能是在 Java 5 发布之前编写的(因此,在“iterable”这个词之前意味着 Java 开发人员的 java.util.Iterable 接口)。
  • 抱歉,问题已解决,我打字时看错了。
  • @Loadmaster:不,不应该!但它应该有一个compareTo() 方法! :)

标签: java interface iterator iterable


【解决方案1】:

您的Iterator 必须实现Iterator 接口中的所有方法才能封装迭代逻辑。

在您的情况下,它必须保存数组中的当前迭代索引。你可以从 commons-collections 中查看ArrayIterator

【讨论】:

  • 我很困惑,在我的情况下您将如何实施?
  • 正如我所说:) 保持当前迭代索引。 commons-collections 是开源的,所以看看那里的代码。
【解决方案2】:

最简单的做法可能是创建一个填充了things 中的值的new ArrayList&lt;String&gt;(),并将调用结果返回到其.iterator() 方法。这当然是我在时间有限的情况下(比如考试)会做的事情,而且很可能是我在现实世界中会做的事情,只是为了让事情变得简单。

您可以编写自己的 ArrayIterator 类,或者使用您可以在网络上找到的各种库中的一个,但这似乎会增加不必要的复杂性。

【讨论】:

    【解决方案3】:
    private class PartialIterableClass implements Iterable<String> {
        private String[] things;
        public PartialIterableClass( String[] things ){
            this.things = things;
        }
    
        @Override
        public Iterator<String> iterator() {
            return Arrays.asList(things).iterator();
        }
    }
    

    【讨论】:

    • 您将数组转换为内存中的临时列表只是为了对其进行迭代?!
    • Arrays.asList() 几乎没有“转换”。它只是用 List 视图装饰原始数组,使用私有帮助器类 java.util.Arrays.ArrayList
    • 您基本上是在创建一个对数组的引用列表,这也是必须分配的额外空间。链接:docs.oracle.com/javase/6/docs/api/java/util/…
    • 您在“对数组的引用列表”中迷失了我,但如果我们要继续进行下去,我们可能应该将此对话移至聊天。现在,我会坚忍地接受你的反对票。 :)
    • 创建一个列表来获取迭代器是没有人想要的显而易见的答案,您已经知道这不是一个真正的解决方案,如果数组大小很大,它可能会很昂贵。而且我不喜欢兔子洞,所以我不会谈论这个。
    【解决方案4】:

    你可以使用ArrayIterator,或者像这样构建你自己的迭代器:

    package arrayiterator;
    
    import java.util.concurrent.locks.Lock;
    import java.util.concurrent.locks.ReentrantLock;
    
    class ArrayIterator_int
    {
    
        public static void main(String[] args)
        {
            int [] arr = { 5, 4, 3, 2, 1 };
    
            ArrayIterator_int iterator = new ArrayIterator_int(arr);
    
            while (iterator.hasNext())
            {
                System.out.println("  " + iterator.next());
            }
        }
    
        private int cursor;
        private final int [] array;
        private static final Lock lock = new ReentrantLock();
    
        public ArrayIterator_int (int [] array)
        {
            this.array = array;
            this.cursor = 0;
        }
    
        public boolean hasNext ()
        {
            boolean hasNext = false;
            lock.lock();
    
            try
            {
                hasNext = ((this.cursor+1) < this.array.length);
            }
            catch(Exception e)
            {
                e.printStackTrace();
            }
            finally
            {
                lock.unlock();
                return hasNext;
            }
    
        }
    
        public int next () throws ArrayIndexOutOfBoundsException
        {
            int next = 0;
            lock.lock();
    
            try
            {
                next = this.array[++this.cursor];
            }
            catch(ArrayIndexOutOfBoundsException e)
            {
                throw e;
            }
            catch(Exception e)
            {
                e.printStackTrace();
            }
            finally
            {
                lock.unlock();
                return next;
            }
        }
    
        public int read () throws ArrayIndexOutOfBoundsException
        {
            int read = 0;
            lock.lock();
    
            try
            {
                read = this.array[this.cursor];
            }
            catch(ArrayIndexOutOfBoundsException e)
            {
                throw e;
            }
            catch(Exception e)
            {
                e.printStackTrace();
            }
            finally
            {
                lock.unlock();
                return read;
            }
        }
    
        public void write (int newVal) throws ArrayIndexOutOfBoundsException
        {
            lock.lock();
    
            try
            {
                this.array[this.cursor] = newVal;
            }
            catch(ArrayIndexOutOfBoundsException e)
            {
                throw e;
            }
            catch(Exception e)
            {
                e.printStackTrace();
            }
            finally
            {
                lock.unlock();
            }
        }
    
    }
    

    【讨论】:

      猜你喜欢
      • 2010-10-10
      • 2011-02-25
      • 2017-08-18
      • 2015-12-13
      • 2021-09-14
      • 2020-11-05
      • 1970-01-01
      • 2020-01-24
      • 1970-01-01
      相关资源
      最近更新 更多