Stack in Java, problem with “contains”

|▌冷眼眸甩不掉的悲伤 提交于 2019-12-05 21:01:01

the int[] array objects have no way of knowing if two arrays are equal because they are in effect just pointers, and since they are pointing to two different arrays, they are considered unequal. The reason why the pointers are used to compare equality is because the Object class defines the most rudimentary equals method in such a fashion.

You need to create a simple class to encapsulate your array. Here is a simple one anyone could understand.

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;
        }
    }
}

Once this is done, you can easily do something like you have done before:

    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");
    }

That should definitely work.

That's simple: int[] get compared by identity,

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

returns false. There are many solutions:

  • Use List<Integer> instead. That's quite inefficient, but may suffice.
  • Wrap the int[] into an object and implement equals and hashCode.
  • Use a primitive collection library like trove4j which provides things similar to List<int>

To get it to print "YES" you need to make the stack be of some object that has defined equals() and hashCode() such that two arrays with identical elements will be considered equal.

So something like this (which is just dashed off and probably could be better):

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
    }
}

And then have your Stack be Stack<ArrayHolder>.

One option is to use a wrapper, like

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);
    }
}

Another fix would be to override contains, as in

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

The contains() method relies on the result of equals() - if you want full control, subclass and over-ride equals() to mean what you intend.

ax123man

First you have to define what "contains" means. The docs for Stack.contains say:

Returns: true if and only if the specified object is the same as a component in this vector, as determined by the equals method.

(Stack extends Vector)

So you could create your own class that has an array of ints as an instance variable and override "equals" on that class to implement what ever that means in your case. Just make sure you do this properly. Information on how to do that is everwhere

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!