【问题标题】:Any reason why my Vector is losing its data?我的 Vector 丢失数据的任何原因?
【发布时间】:2020-07-02 19:32:37
【问题描述】:

我目前的目标是将对象添加到向量中,以便由我创建的另一个类中的迭代器访问(对于这个项目,我不允许使用 Java 的迭代器)。我的迭代器函数应该返回向量内的特定对象。相反,迭代器在向量中报告空值。经过调试,问题是在启动时添加对象后,对象消失了。将向量传递给迭代器类并不能解决问题。我试过使用数组列表而不是向量,但没有成功。

public void init() { //where im doing the adding
    for (int i = 0; i < 1; i++) {
        cyborg = new Player(ColorUtil.rgb(42, 194, 225), 50, 46.0, baseLocations[0], 40, 100, 100, 0, 50, true);
        go.add((Player) cyborg);
    }

    for (int i = 0; i < 3; i++) {
        NPC = new NPC(ColorUtil.rgb(42, 194, 225), 50, 46.0, baseLocations[0], 40, 100, 100, 0, 50, currStrat);
        go.add((NPC) NPC);
    }

    for (int i = 0; i < 2; i++) {
        drone = new Drone(ColorUtil.rgb(82, 95, 81), r.nextInt(50), 10.0,
                new Point(r.nextFloat() * 1000, r.nextFloat() * 1000), r.nextInt(50));
        go.add(drone);
    }

    for (int i = 0; i < 4; i++) {
        base = new Base(ColorUtil.rgb(169, 235, 0), baseSequence++, baseLocations[i], 10);
        go.add((Fixed) base);
    }

    for (int i = 0; i < 2; i++) {
        eStation = new eStation(ColorUtil.rgb(100, 85, 85), new Point(r.nextFloat() * 1000, r.nextFloat() * 1000),
                r.nextInt(50), 100);
        go.add((Fixed) eStation);

    }



public class GameCollection implements ICollection {

private Vector<GameObject> gameCollection;

public GameCollection() {
    gameCollection = new Vector<GameObject>(); //the vector im having problems with
    System.out.println(gameCollection.toString()); //Test to check if objects in game collection array. Prints null values after startup
}

public IIterator getIterator() {

    GameCollectionIterator gameItr = new GameCollectionIterator(gameCollection);
            return gameItr;


}

public void add(GameObject o) {
    gameCollection.addElement(o);
    //System.out.println(super.toString());
}



public Object elementAt(int location) {
    if(location < gameCollection.size()) {
        return (Object) gameCollection.indexOf(location);
    }

     throw new ArrayIndexOutOfBoundsException(location);

}
public void remove(GameObject o) {
    // TODO Auto-generated method stub
    gameCollection.remove(gameCollection.indexOf(o));
}




private class GameCollectionIterator implements IIterator{
    private int currIndex = 0;

    private Vector <GameObject> game = new Vector <GameObject>();

    public GameCollectionIterator(Vector<GameObject> g) {
        game = g;
    }


    @Override
    public boolean hasNext() {
        if(game.size() <= 0){
            System.out.println("First case");
            return false;

        }
        if(currIndex == game.size() -1){
            System.out.println("Second case");
            return false;
        }
        return true;
    }

    @Override
    public Object getNext() {
        currIndex++;
        return(game.indexOf(currIndex));
    }





    @Override
    public void remove() {
        game.remove(currIndex);
    }

}

【问题讨论】:

  • 阅读this article 了解调试代码的技巧。如果您仍需要帮助,请创建一个 minimal reproducible example,我们可以复制/粘贴并自行运行,并查看您所询问的相同行为。

标签: java vector iterator


【解决方案1】:

我可以在这里看到您的迭代器存在一些问题:

@Override
public Object getNext() {
    currIndex++; // (1)
    return(game.indexOf(currIndex)); // (2)
}
  1. currIndex++; - 在从向量中获取元素之前增加索引,因此您基本上总是跳过第一个元素(索引为 0)。

  2. game.indexOf(currIndex) - indexOf 返回指定元素第一次出现的索引,参见doc。您必须改用get 方法,请参阅doc

【讨论】:

    【解决方案2】:

    首先,我们实际上看不到发生了什么,因为您没有提供一种“驱动程序”以便我们了解如何这些类是如何被使用的。 p>

    但是,我怀疑问题在于您的GameCollectionIterator 不正确。它有很多问题,包括:

    1. next 方法假设存在下一个元素。它不是在检查。 (好吧,我们不知道IIterator 合约所说的应该发生什么,但这很可疑。)

    2. 正如@rxn1d 还指出的那样,next 在使用之前会增加currIndex(从零开始)。这意味着迭代器在大多数情况下会跳过第一个元素。

    3. @rxn1d 关于return(game.indexOf(currIndex)); 也是正确的。该声明实际上将:

      • currIndex 自动装箱到Integer
      • 尝试在列表中查找Integer
      • 失败...给出int-1,并且
      • 自动装箱并返回那个1
    4. 迭代器实现中没有任何内容可以检测迭代时添加或删除元素的情况。当您移除任何对象时,移除点之外的剩余对象的位置将发生变化。但是您并没有为此调整currIndex。因此,删除可能会导致对象被跳过。

    5. 迭代器不是线程安全的。 (不清楚这是否重要......)

    请注意,java.util.Collection 的标准(非并发)实现将检测并发修改并精确地抛出异常以避免出现类似 4 的问题。


    其他一些需要更正的地方。

    • 您应该在其他人阅读您的代码之前去掉多余的空行和自动生成的 cmets2

    • 我不明白您为什么要使用自己的 IIteratorICollection 接口......或者它们的实际含义。 (声明在哪里?javadocs 在哪里?)

    • 您的throw new ArrayIndexOutOfBoundsException(location); 抛出了错误的异常。您的集合不是数组。

    • eStation 是一个错误的类名。类名 always 以大写字母开头。然后通过声明一个与其类同名的变量来复合它。

    • 假设eStationGameObject 的子类型,go.add((Fixed) eStation); 中的类型转换是不必要的。其他例子。


    1 - 我很惊讶您没有注意到 next 正在返回 Integer 对象。或者如果你这样做了,你认为它不够重要,可以提及。

    2 - 在向其他人展示您的代码并要求他们阅读之前,您应该始终这样做。像对待未来的同事一样对待我们。

    【讨论】:

      猜你喜欢
      • 2012-11-07
      • 1970-01-01
      • 1970-01-01
      • 2013-08-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-07-04
      相关资源
      最近更新 更多