clankill3r
clankill3r

Reputation: 9583

contains fails with ArrayList

the following is part of a big library i write so i only show a small piece of code. If more is required, let me know.

I'm making a tool where i can select anchors of a bezier. The strange thing is, i select one anchor for example. Then i can hold shift for a toggle selection, where unselected anchors get selected and selected ones get unselected. I select the same anchor. Then in the first line of code it check if it was in the ArrayList lastAnchorSelection. It was part but for some reason it continues. Then it reports the size of the last selection, which is 1. Then i get the object out of the arrayList and test it against v, it print out true.

So how can the first line result in false where the 4th line results in true?

if (lastAnchorSelection.contains(v) == false) {
  System.out.println("lastAnchorSelection.size(): "+lastAnchorSelection.size());
  CVector test = lastAnchorSelection.get(0);
  System.out.println(test == v);
  System.out.println("C");

Upvotes: 1

Views: 991

Answers (3)

Olaf Dietsche
Olaf Dietsche

Reputation: 74118

From ArrayList

Returns true if this list contains the specified element. More formally, returns true if and only if this list contains at least one element e such that (o==null ? e==null : o.equals(e)).

In your case, this would be v.equals(test). When this returns false, contains(v) returns false as well.

Line 4 compares v == test, which is a different comparison than v.equals(test).

v == test compares the references of v and test. When v and test reference the same object, this returns true. Whereas v.equals(test) calls the method equals, which might return anything (even false) depending on its implementation.

Upvotes: 0

Ian Roberts
Ian Roberts

Reputation: 122424

Collection.contains is specified in terms of the equals() method. Implementations of equals() are supposed to follow a number of rules (see the Object class javadoc), the first of which is

  • It is reflexive: for any non-null reference value x, x.equals(x) should return true.

but it looks like the class of v has a non-compliant equals() implementation that breaks this rule.

Either that or it's a threading issue, and some other thread is adding v to the list in between the contains() test and the get(0).

Upvotes: 4

Nikolay Kuznetsov
Nikolay Kuznetsov

Reputation: 9579

First line uses equals() to compare, the second one compares references.

Upvotes: 2

Related Questions