2017-03-07 79 views
-2

我试图实现一个记住最后N个元素的环。它添加元素并正确更改指针。 get()方法必须返回添加到环中的最新元素。我试图用笔和纸在get方法中找到逻辑,最终,我设法做到了。但是,当我运行我的代码时,它似乎并不如此。我在这里先向您的帮助表示感谢。Java Ring实现

[1] [2] [3] [4] [5] < - 在以下的例子中,得到(0)必须返回5,并获得(1) - 4

迭代与打印

[1] [2] [3] [4] [5]

使用GET方法 - 获取(0),得到(1)....

[1] [5] [ 4] [3] [2] - 这里[1]必须在[2]的右侧

import java.util.AbstractCollection; 
import java.util.ArrayList; 
import java.util.Collection; 
import java.util.Iterator; 

public class CircularArrayRing<E> extends AbstractCollection<E> implements Ring<E> 
{ 

    private int elements; 
    private int front; 
    private E[] ring; 

    @SuppressWarnings("unchecked") 
    public CircularArrayRing() 
    { 
     ring = (E[]) new Object[10]; 
     front = 0; 
    } 

    @SuppressWarnings("unchecked") 
    public CircularArrayRing(int size) 
    { 
     ring = (E[]) new Object[size]; 
     front = 0; 
    } 

    @Override 
    public boolean add(E e) 
    { 

     ring[front] = e; 
     front++; 

     if(front == ring.length) 
     { 
      front = 0; 
     } 

     if(elements < ring.length) 
     { 
      elements++; 
     } 

     return false; 
    } 

    @Override 
    public Iterator<E> iterator() 
    { 

     return null; 
    } 

    @Override 
    public int size() 
    { 
     return elements; 
    } 

    @Override 
    public E get(int index) throws IndexOutOfBoundsException 
    { 
     if(index > elements - 1 || index > ring.length - 1) 
     {  
      throw new IndexOutOfBoundsException(); 
     } 
     else 
     {  
      if (index > front) 
      { 
       return ring[ring.length + front -index]; 
      } 
      else 
      { 
       return ring[front - index]; 
      } 

     } 

    } 

} 
+1

调试并没有帮助,请参阅:什么是调试器和它如何可以帮助我诊断问题?](http://stackoverflow.com/q/25385173/5221149) – Andreas

回答

0

数组索引处理有一些错误。

例如,如果我们看一下基本情况,只需1个元素,调用get(0)的逻辑是:

front - index = 1 - 0 = 1 ->ArrayIndexOutOfBounds

从这我们可以看到,front应减少1以达到正确的指数。

进一步的测试将显示相同的修补程序也应该应用于if的另一个分支,并且条件本身应该是>=而不是>

get正确的代码将被:

if (index >= front) { 
    return ring[ring.length + front - 1 - index]; 
} 
else { 
    return ring[front - 1 - index]; 
} 
+0

“return ring [ring.length + front - 1 - index]”无法访问。当初始化给定大小的对象(比如说3)时,当添加最后一个元素时,它会抛出ArrayIndexOutOfBoundsException异常。 他几乎所有的实现都是错误的。 – LppEdd

+0

@LppEdd它不可及,也似乎一切正常,我有任何例子显示相反? –

+0

尝试用3个元素初始化集合。添加三个元素,然后得到0,1,2 – LppEdd

0

所以,在你的实现看起来稍微好一些后,我试着重写它。
无需初始化sizeeffectiveSize,因为它们的默认值是0作为类成员。
我认为这仍然是你想要的。

public class CircularArrayRing<E> extends AbstractCollection<E> 
{ 
    private final E[] ring; 
    private int size; 
    private int effectiveSize; 

    @SuppressWarnings("unchecked") 
    public CircularArrayRing() { 
     ring = (E[]) new Object[10]; 
    } 

    @SuppressWarnings("unchecked") 
    public CircularArrayRing(final int size) { 
     ring = (E[]) new Object[size]; 
    } 

    @Override 
    public boolean add(final E e) { 
     if (effectiveSize < ring.length) { 
     effectiveSize++; 
     } 

     if (size >= ring.length) { 
     size = 0; 
     } 

     ring[size++] = e; 
     return true; 
    } 

    @Override 
    public Iterator<E> iterator() { 
     return null; 
    } 

    @Override 
    public int size() { 
     return effectiveSize; 
    } 

    public E get(final int index) throws IndexOutOfBoundsException { 
     if (index < 0 || index > effectiveSize - 1) { 
     throw new IndexOutOfBoundsException(); 
     } 

     return ring[effectiveSize - index - 1]; 
    } 
} 
+0

我仍然不知道如何发生这种情况如果我改变这行代码来匹配你的我得到ArrayIndexOutOfBounds –

+0

发布你如何使用这门课。 – LppEdd

+0

@RadoslavTodorov查看最新的答案。 – LppEdd