在Java中堆栈,问题与“包含”

时间:2011-04-19 22:50:50

标签: java stack contains

我在我的程序中使用堆栈,但是当程序试图检查堆栈中包含哪些元素时,我遇到了问题。我在Stack中使用整数数组。简短的例子是:

        Stack<int[]> myStack = new Stack<int[]>();
        myStack.push(new int[]{1,2});
        myStack.push(new int[]{1,3});
        myStack.push(new int[]{1,4});
        if (myStack.contains(new int[]{1,3})) {
            System.out.println("YES");
        } else {
            System.out.println("NO");
        }

现在它被打印为“NO”。我怎么能得到“是”? 我知道问题是我没有使用相同的对象,但在现实中我的程序要大得多,我不能使用这个

int[] myInteger = new int[]{1,3};
myStack.push(myInteger);
myStack.contains(myInteger);

6 个答案:

答案 0 :(得分:6)

这很简单:int[]按身份进行比较,

new int[]{1,3}.equals(new int[]{1,3})

返回false。有很多解决方案:

  • 请改用List<Integer>。这是非常低效的,但可能就足够了。
  • int[]包裹到对象中并实施equalshashCode
  • 使用像trove4j这样的原始集合库,它提供与List<int>
  • 类似的东西

答案 1 :(得分:1)

要使其打印“YES”,您需要使堆栈成为定义equals()hashCode()的某个对象,以便将具有相同元素的两个数组视为相等。

所以这样的事情(它可能会更好,可能会更好):

public class ArrayHolder
{
    private int[] theArray;

    public ArrayHolder(int[] theArray) {
       this.theArray = theArray;
    }

    public array() {
        return theArray;
    }

    public boolean equals(Object o) {
        // Code that will return true if
        // o is an int[] that contains the
        // same elements as this
    }

    public int hashCode() {
        // code that will return a hash
        // based on the array elements so
        // that arrays with the same elements
        // will have the same hash
    }
}

然后让Stack成为Stack<ArrayHolder>

答案 2 :(得分:1)

一种选择是使用包装器,如

class ArrayWrapper {
    int[] data;

    public boolean equals(Object o) {
        if (o instanceof ArrayWrapper)
            return Arrays.equals(data, ((ArrayWrapper) o).data);
        return false;
    }

    public int hashCode() {
        return Arrays.hashCode(data);
    }
}

另一种解决方法是覆盖contains,如

class SmartStack extends Stack<int[]> {
    @Override
    public boolean contains(Object o) {
        ...
    }
}

答案 3 :(得分:1)

int []数组对象无法知道两个数组是否相等,因为它们实际上只是指针,并且因为它们指向两个不同的数组,所以它们被认为是不相等的。指针用于比较相等性的原因是因为Object类以这种方式定义了最基本的equals方法。

您需要创建一个简单的类来封装您的数组。 这是一个任何人都能理解的简单。

class IntArray {
    int[] myArray;
    public IntArray () {
        myArray = new int[0];
    }
    public IntArray (int [] array) {
        myArray = array;
    }
    /**
     * This method is for accessing the array.
     * The array CAN be modified using this method.
     */
    public int[] getArray() {
        return myArray;
    }
    /**
     * Uses built-in hashCode generating method
     * within the Arrays class.
     * Importing java.util.Arrays is necessary.
     */
    public int hashCode() {
        return Arrays.hashCode(myArray);
    }
    public boolean equals(Object o) {
        if (!(o instanceof IntArray))
            return false;

        //Should use Arrays.equals(o.myArray, myArray);

        if (o.myArray.length != myArray.length)
            return false;
        else {
            for (int i = 0; i < myArray.length; i++) {
                if (myArray[i] != o.myArray[i]) {
                    return false;
                }
            }
            return true;
        }
    }
}

完成此操作后,您可以轻松地执行以前的操作:

    Stack<In> myStack = new Stack<int[]>();
    myStack.push( new IntArray (new int[]{1,2}) );
    myStack.push( new IntArray (new int[]{1,3}) );
    myStack.push( new IntArray (new int[]{1,4}) );
    if (myStack.contains( new IntArray (new int[]{1,3})) ) {
        System.out.println("YES");
    } else {
        System.out.println("NO");
    }

这绝对有用。

答案 4 :(得分:0)

contains()方法依赖于equals()的结果 - 如果你想要完全控制,子类和覆盖equals()来表示你的意图。

答案 5 :(得分:0)

首先,您必须定义“包含”的含义。 Stack.contains的文档说:

  

返回:当且仅当指定的对象与此向量中的组件相同时才返回true,由equals方法确定。

(Stack extends Vector)

因此,您可以创建自己的类,其中包含一个int数组作为实例变量,并在该类上覆盖“equals”以实现您的情况下的意义。只要确保你做得好。有关如何执行此操作的信息是everwhere