4

I have an ArrayList containing objects which have 4 parameters (x, y, iD and myType). I want to verify if there are objects in this ArrayList which have particular coordinates, independently of their iD and myType parameters. I wanted to use Arrays.asList(yourArray).contains(yourValue) but it is when the object has only one parameter.

Here is the whole code:

public class MyObject {

  public float x;
  public float y;
  public int iD;
  public String myType;


  public MyObject (float x, float y, int iD, String myType) 
  {
    this.myType = myType;
    this.iD = iD;
    this.x = x;
    this.y = y;
  }
  @Override
    public String toString() {
    return ("[iD="+iD+" x="+x+" y="+y +" type="+myType+"]");
  }
}


ArrayList<MyObject> myArrayList = new ArrayList<MyObject>();

void setup() 
{
  size(100, 60);
  myArrayList.add(new MyObject(3.5, 4.5, 6, "a"));
  myArrayList.add(new MyObject(5.4, 2.6, 4, "b"));
}

For example, if I want to verify if there is an object which has the coordinates (3.5, 4.5), how should I proceed ? Is there an easy way to do this ?

thanks for your help

Sotirios Delimanolis
  • 274,122
  • 60
  • 696
  • 724
Graham Slick
  • 6,692
  • 9
  • 51
  • 87

2 Answers2

5

The javadoc of List#contains(Object) states

Returns true if this list contains the specified element.

That's not what you're trying to do here. You're not specifying an element, you want to specify properties of an element. Don't use this method.

The long form solution is to iterate over the elements in the List and check them individually, returning true as soon as you find one, or false when you run out of elements.

public boolean findAny(ArrayList<MyObject> myArrayList, float targetX) {
    for (MyObject element : myArrayList) {
        if (element.x == targetX) { // whatever condition(s) you want to check
            return true;
        }
    }
    return false;
}

Since Java 8, there's a better way to do this using Stream#anyMatch(Predicate) which

Returns whether any elements of this stream match the provided predicate.

Where the given Predicate is simply a test for the properties you're looking for

return myArrayList.stream().anyMatch((e) -> e.x == targetX); 

Regarding equality checks for floating point values, see the following:

Community
  • 1
  • 1
Sotirios Delimanolis
  • 274,122
  • 60
  • 696
  • 724
2

You can override equals function to define equal:

public class MyObject {

    public float x;
    public float y;
    public int iD;
    public String myType;


    public MyObject (float x, float y, int iD, String myType)
    {
        this.myType = myType;
        this.iD = iD;
        this.x = x;
        this.y = y;
    }
    @Override
    public String toString() {
        return ("[iD="+iD+" x="+x+" y="+y +" type="+myType+"]");
    }

    @Override
    public boolean equals(Object o) {
        if (o instanceof MyObject) {
            MyObject myObject = (MyObject) o;
            return myObject.iD == this.iD && myObject.myType.equals(this.myType);
        }

        return false;
    }
}

Attention:

I must admit it's dangerous way to do this. override equals maybe will cause strange issues in program if you have used equals do some other compares. but in special case, maybe you can do that.

chengpohi
  • 14,064
  • 1
  • 24
  • 42
  • Thanks for answering ! And then I use myArrayList.contains((3.5, 4.5)); ? – Graham Slick Jul 15 '15 at 01:28
  • @MatthiasGrahamSlick You would need to have nested `for` loops to check whether each pair of elements is "equal". Or if you already know that you are looking for (3.5,4.5) you could use `List.indexOf(Object)` to get and remove the first object and if call `indexOf` again and it returns `-1` it will mean there is only one such object while if it is a positive integer it will mean there are two objects with (3.5,4.5). – M. Shaw Jul 15 '15 at 01:42
  • This is a bad idea. They want to use `contains`. With overriding equals, they'd have to create a new object with garbage id and type. Instead, they should iterate over each element and compare only those properties which are relevant. – Sotirios Delimanolis Jul 15 '15 at 01:47
  • @M.Shaw thanks for your help. I don't need to check if there is only one, I need to check if there is at all an object which have these coordinates or not ... – Graham Slick Jul 15 '15 at 01:47
  • With Java 8s `Stream` and `filter` it's easier. – Sotirios Delimanolis Jul 15 '15 at 01:47
  • Having `equals` compare a subset of fields sounds dangerous – NamshubWriter Jul 15 '15 at 04:42