如何在Java中创建处理泛型和数组的grab方法

如何在Java中创建处理泛型和数组的grab方法,java,arrays,object,generics,Java,Arrays,Object,Generics,因此,我正在创建一个名为Sack的通用数据结构。在这个过程中,我将物品添加到一个袋子中,抓取一个随机物品,查看它是否为空,或者转储它的内容等。此外,我创建它是为了扩展以容纳所需数量的物品 我需要创建一个抓取方法,该方法可以随机从袋子中移除并返回一个物品。如果不存在任何项,则应返回null 我的代码如下: public class Sack<E> { public static final int DEFAULT_CAPACITY = 10; private E [] elementD

因此,我正在创建一个名为Sack的通用数据结构。在这个过程中,我将物品添加到一个袋子中,抓取一个随机物品,查看它是否为空,或者转储它的内容等。此外,我创建它是为了扩展以容纳所需数量的物品

我需要创建一个抓取方法,该方法可以随机从袋子中移除并返回一个物品。如果不存在任何项,则应返回null

我的代码如下:

public class Sack<E>
{
public static final int DEFAULT_CAPACITY = 10;
private E [] elementData;
private int size;

@SuppressWarnings("unchecked")
public Sack()
{
    elementData = (E[]) new Object[DEFAULT_CAPACITY];
}
@SuppressWarnings("unchecked")
public Sack(int capacity)
{
    if(capacity < 0)
    {
        throw new IllegalArgumentException("capacity " + capacity);
    }
    this.elementData = (E[]) new Object[capacity];
}
public boolean isEmpty()
{
    if(size == 0)
    {
        return true;
    }
    else
    {
        return false;
    }
}
public void add(E item)
{
    int index = size++;
    if(size >= elementData.length-1)
    {
        elementData = Arrays.copyOf(elementData, size);
    }
    elementData[index] = item;
}
public E [] dump()
{
   E [] E2 = Arrays.copyOf(elementData, size);
   for(int i = 0; i < size; i++)
   {
      elementData[i] = null;
   }
   size = 0;
    return E2;
}
这是不正确的,我在运行测试时收到一个错误,声明AssertionFailedError:grab无法正常工作检查空sack ==>

应为空

实际值:[Ljava.lang.Object;@76908cc0

我的测试就在这里,我不能修改我的测试,只有提供的代码,因为那里有一个错误,我需要帮助我之前所说的:

抓取方法应随机从袋子中取出并返回物品。如果没有物品 如果存在,则应返回null

因此,以下是我的测试:

 @Test
 public void testGrab()
 {
    assertNull(s.grab(), "grab is not working correctly (check with empty sack)");
    Random rand = new Random();
    int numElements = rand.nextInt(9) + 1;
    Integer[] setElementData = new Integer[10];
    ArrayList<Integer> expectedElements = new ArrayList<Integer>();
    int randElement;
    for(int i=0; i<numElements; ++i) {
        randElement = rand.nextInt(50) + 1;
        if(!expectedElements.contains(randElement)) {
            setElementData[i] = randElement;
            expectedElements.add(randElement);
        } else {
            --i;
        }
    }
    try {
        elementData.set(s, setElementData);
        size.set(s, numElements);
        for(int i=0; i<numElements; ++i) {
            expectedElements.remove(s.grab());
            assertEquals(numElements-i-1, size.get(s), "grab is not working correctly (check size usage)");
        }
        assertEquals(0, expectedElements.size(), "grab is not working correctly (check size usage)");
    } catch (Exception e) {
        fail("grab is not working correctly");
    }
}

请告诉我,对于如何完成此任务,您是否对我的grab方法有任何解决方案。

我不明白为什么您的grab方法返回数组而不是单个元素。我可以建议您使用不同的方法

public class Sack<E> {
    private final static int DEFAULT_CAPACITY = 10;
    private final static float REALLOC_FACTOR = 1.5f;
    private E[] elementData;
    private int size;

    public Sack() {
        this(DEFAULT_CAPACITY);
    }
    @SuppressWarnings("unchecked")
    public Sack(int capacity) {
        if(capacity <= 0)
            throw new IllegalArgumentException("capacity " + capacity);
        elementData = (E[]) new Object[capacity];
    }
    public boolean isEmpty() {
        return size == 0;
    }
    public void add(E item) {
        int index = size++;
        if(size > elementData.length-1)
            elementData = Arrays.copyOf(elementData, (int)(size*REALLOC_FACTOR));
        elementData[index] = item;
    }
    public E [] dump() {
       E [] E2 = Arrays.copyOf(elementData, size);
       Arrays.fill(elementData, null);
       size = 0;
       return E2;
    }
    public E grab() {
        if(size == 0)
            return null;
        int index = (int)(Math.random()*size);
        E element = elementData[index];
        elementData[index] = elementData[size-1];
        elementData[size-1] = null;
        size--;
        return element;
    }
}
这个grab方法背后的思想是选择一个随机索引rand,从0到effectiveSize-1,然后返回这个元素,但是在我们必须将这个元素与最后一个元素交换之前,先使用index effectiveSize-1的元素并减小有效大小。我使用了Math.rand,因为当第一次调用它时,它会创建一个新的伪随机数mber生成器,然后此生成器用于此方法的所有调用


注意:我还添加了一个realloc因子,以避免在数组饱和后每个元素的数组realloc。

以下是更简单的答案。我将@Mirko Alicastro归功于@Mirko

public E grab()
{
    if(size == 0)
        return null;
    int index = (int) (Math.random() * size);
        E element = elementData[index];
        elementData[index] = elementData[size - 1];
        elementData[size - 1] = null;
        size--;

    return element;
}

这是另一种解决方法

public E grab()
{
      if(isEmpty())
      {
         return null;
      }
      Random rand = new Random();
      int i = rand.nextInt(size);
      E item = elementData[i];
      remove(i);
      return item;
}

谢谢,我稍后会看一看并向您报告。好的,我已经尝试过了,在尝试返回元素时收到一个错误。它应该是E[]现在发现的只是一个E。请解释grab方法必须做什么,因为它不清楚:你说grab方法应该随机从袋子中移除并返回一个项目,所以这个方法不能返回数组,而只能返回一个元素。grab方法应该随机移除并返回袋子中的一个项目。如果没有项目,则e present,它应该返回null。谢谢,我自己在代码中犯了一个错误。这很好用。
public E grab()
{
      if(isEmpty())
      {
         return null;
      }
      Random rand = new Random();
      int i = rand.nextInt(size);
      E item = elementData[i];
      remove(i);
      return item;
}