Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Evaluating objects containing Strings with Java ArrayList contains()

Tags:

java

arraylist

I would like to do a deeper String check of Objects to be able to do the following:

List<MyObj> myList = new ArrayList<MyObj>() {{
    add(new MyObj("hello"));
    add(new MyObj("world"));
}};

System.out.println(myList.contains("hello")); // true
System.out.println(myList.contains("foo")); // false
System.out.println(myList.contains("world")); // true

But getting false on each one with the following full code

/* Name of the class has to be "Main" only if the class is public. */
class Ideone {
    public static class MyObj {
        private String str;
        private int hashCode;

        public MyObj(String str) {
            this.str = str;
        }

        public @Override boolean equals(Object obj) {
            System.out.println("MyObj.equals(Object)");
            if (obj == this) {
                return true;
            }

            if (obj instanceof String) {
                String strObj = (String) obj;
                return strObj.equals(str);
            }

            return false;
        }

        public @Override int hashCode() {
            if (hashCode == 0) {
                hashCode = 7;
                for (int i = 0; i < str.length(); ++i) {
                    hashCode = hashCode * 31 + str.charAt(i);
                }
            }

            return hashCode;
        }
    }

    public static final MyObj obj1 = new MyObj("hello");
    public static final MyObj obj2 = new MyObj("world");
    public static void main (String[] args) throws java.lang.Exception {
        List<MyObj> myList = new ArrayList<MyObj>() {{
            add(obj1);
            add(obj2);
        }};

        System.out.println(myList.contains("hello"));
        System.out.println(myList.contains("foo"));
        System.out.println(myList.contains("world"));
    }
}

If I'm right the List Object should use equals() and hashCode() to evaluate containing Objects. So I @Override them and check their Strings additionally. But it never gets into equals() as there's no output MyObj.equals(Object).

like image 277
dtrunk Avatar asked Dec 11 '22 10:12

dtrunk


1 Answers

java.util.ArrayList#indexOf is used internally in ArrayList for contains().

There is a check,

o.equals(elementData[i])

So there is comparison of string with your object, so String.equals() is invoked for check of equality.

like image 65
Admit Avatar answered Jan 11 '23 23:01

Admit