Java 在堆栈的ArrayList中,如果堆栈为空,为什么索引不正确?

Java 在堆栈的ArrayList中,如果堆栈为空,为什么索引不正确?,java,arraylist,stack,indexof,Java,Arraylist,Stack,Indexof,我有一个堆栈的ArrayList,其中我向其中一个堆栈添加了一个元素,并在列表中迭代打印每个堆栈的索引。 然后,我从上一个堆栈中删除元素,将其添加到下一个堆栈中,打印每个堆栈的索引,并对ArrayList中的所有堆栈继续此操作。 但是,当任何堆栈为空时,在获取ArrayList中每个堆栈的索引时会出现非常不寻常的行为。不为空的堆栈将具有正确的索引值,而为空的堆栈将具有不正确的索引值。 此外,如果包含元素的堆栈的索引为0,则所有其他索引值都将为1。如果包含元素的堆栈位于任何其他索引处,它将具有正确

我有一个堆栈的ArrayList,其中我向其中一个堆栈添加了一个元素,并在列表中迭代打印每个堆栈的索引。 然后,我从上一个堆栈中删除元素,将其添加到下一个堆栈中,打印每个堆栈的索引,并对ArrayList中的所有堆栈继续此操作。 但是,当任何堆栈为空时,在获取ArrayList中每个堆栈的索引时会出现非常不寻常的行为。不为空的堆栈将具有正确的索引值,而为空的堆栈将具有不正确的索引值。 此外,如果包含元素的堆栈的索引为0,则所有其他索引值都将为1。如果包含元素的堆栈位于任何其他索引处,它将具有正确的索引值,并且所有其他索引值都将为0。 这是我的密码:

import java.util.List;
import java.util.Stack;
import java.util.ArrayList;

public class ListOfStacks {

    // instance variables:
    List<Stack<Integer>> stacks;
    private static final int NUMBER_OF_STACKS = 3;

    // constructor:
    ListOfStacks() {
        this.stacks = new ArrayList<Stack<Integer>>(NUMBER_OF_STACKS);

        // adding the stacks to the list here:
        for (int i = 0; i < NUMBER_OF_STACKS; i++) {
            this.stacks.add(new Stack<Integer>());
        }
    }

    // instance methods:
    void addElement(int stackIndex, int element) {
        this.stacks.get(stackIndex).add(element);
    }
    void removeElement(int stackIndex) {
        this.stacks.get(stackIndex).pop();
    }
    void printIndexes(int stackIndex, int element) {
        System.out.printf("The stack at index %d now contains %d" +
            "(the other stacks are empty):%n", stackIndex, element);

        for (Stack<Integer> stack : this.stacks) {
            System.out.printf("index %d%n", this.stacks.indexOf(stack));
        }
        System.out.println();
    }

    // main method:
    public static void main(String[] args) {
        ListOfStacks list = new ListOfStacks();
        int index = 0, number = 5;

        // adding the number 5 to the stack at index 0:
        list.addElement(index, number);
        list.printIndexes(index, number);

        // now removing that element, and adding it to the stack at index 1:
        list.removeElement(index++);
        list.addElement(index, number);
        list.printIndexes(index, number);

        // now removing that element, and adding it to the stack at index 2:
        list.removeElement(index++);
        list.addElement(index, number);
        list.printIndexes(index, number);
    }
} // end of ListOfStacks

得到错误索引号的原因与indexOf在列表中的实现方式有关。在下面,它调用Stack.equals。这将确定堆栈在元素方面是否相等。使用空堆栈调用list.indexOf时,它将返回列表中第一个空堆栈的索引

获取错误索引号的原因与indexOf在列表中的实现方式有关。在下面,它调用Stack.equals。这将确定堆栈在元素方面是否相等。使用空堆栈调用list.indexOf时,它将返回列表中第一个空堆栈的索引

indexOf(Object o) 
          Returns the index of the first occurrence of the specified element in this list, or -1 if this list does not contain the element.
java中的堆栈基本上是一个向量,vector类将其用于equals

 /**
  969        * Compares the specified Object with this Vector for equality.  Returns
  970        * true if and only if the specified Object is also a List, both Lists
  971        * have the same size, and all corresponding pairs of elements in the two
  972        * Lists are <em>equal</em>.  (Two elements {@code e1} and
  973        * {@code e2} are <em>equal</em> if {@code (e1==null ? e2==null :
  974        * e1.equals(e2))}.)  In other words, two Lists are defined to be
  975        * equal if they contain the same elements in the same order.
  976        *
  977        * @param o the Object to be compared for equality with this Vector
  978        * @return true if the specified Object is equal to this Vector
  979        */
  980       public synchronized boolean equals(Object o) {
  981           return super.equals(o);
  982       }
所以现在发生的是indexof找到第一个空堆栈,将其视为相等并返回该索引

因此,当索引0包含元素而其他索引没有元素时,等于空堆栈的第一个堆栈位于位置1

如果另一个元素有数据,并且第一个元素相等,并且您正在查找空堆栈,那么它将始终停止并返回索引0

java中的堆栈基本上是一个向量,vector类将其用于equals

 /**
  969        * Compares the specified Object with this Vector for equality.  Returns
  970        * true if and only if the specified Object is also a List, both Lists
  971        * have the same size, and all corresponding pairs of elements in the two
  972        * Lists are <em>equal</em>.  (Two elements {@code e1} and
  973        * {@code e2} are <em>equal</em> if {@code (e1==null ? e2==null :
  974        * e1.equals(e2))}.)  In other words, two Lists are defined to be
  975        * equal if they contain the same elements in the same order.
  976        *
  977        * @param o the Object to be compared for equality with this Vector
  978        * @return true if the specified Object is equal to this Vector
  979        */
  980       public synchronized boolean equals(Object o) {
  981           return super.equals(o);
  982       }
所以现在发生的是indexof找到第一个空堆栈,将其视为相等并返回该索引

因此,当索引0包含元素而其他索引没有元素时,等于空堆栈的第一个堆栈位于位置1


如果另一个元素有数据,而第一个元素相等,并且您正在寻找一个空堆栈,那么它将始终停止并返回索引0。

Thank@midpips,因此,我是否需要重写.equalsObject o和/或.indexOfObject o以实现正常的索引行为?您可以创建一个扩展堆栈类的类,并将equals方法重写为引用等式。我不知道这是否是最好的方法,但它应该会给你你想要的答案。谢谢@midpips,所以我需要重写.equalsObject o和/或.indexOfObject o来实现正常的索引行为吗?你可以创建一个扩展堆栈类的类,并重写equals方法,使之成为一个引用等式。我不知道这是否是最好的方法,但它应该会给你你想要的答案。谢谢@DeltaLima的帮助,那么我怎样才能用空堆栈实现正常的索引行为呢?嗯。。。如果没有更多的关于你想要达到的目标的知识,这有点难以回答。我想知道选择名单是否正确。一个简单的数组在这里不起作用吗?谢谢@DeltaLima,我以前尝试过使用堆栈数组,但有几个错误,请参见:。我的目的是创建一个合适的结构来解决河内塔的问题。因此,我发现,要初始化堆栈数组,如下所示。stack=new stack[3];,存在警告类型安全:类型Stack[]的表达式需要未经检查的转换才能符合Stack[]。不过,一个可能的解决方案是在构造函数和/或方法上方使用注释@SuppressWarningUnchecked,但可能不安全。不过我不知道为什么。感谢@DeltaLima的帮助,那么我如何在空堆栈上实现正常的索引行为呢?嗯。。。如果没有更多的关于你想要达到的目标的知识,这有点难以回答。我想知道选择名单是否正确。一个简单的数组在这里不起作用吗?谢谢@DeltaLima,我以前尝试过使用堆栈数组,但有几个错误,请参见:。我的目的是创建一个合适的结构来解决河内塔的问题。因此,我发现,要初始化堆栈数组,如下所示。stack=new stack[3];,存在警告类型安全:类型Stack[]的表达式需要未经检查的转换才能符合Stack[]。不过,一个可能的解决方案是在构造函数和/或方法上方使用注释@SuppressWarningUnchecked,但可能不安全,但我不知道为什么。