javalistobjectjavafxobservablelist

contains with ObservableList () returns always false


im using ObservableList in my JavaFX code , i'm trying to test if an object exists in this list but it always returns false even for those already existing in it . here is my code :

private ObservableList<OMission> UserMission = FXCollections.observableArrayList();    

OMission OM1 = new OMission(1,"user_firstname","user_lastname");


UserMission.add(OM1);



if(UserMission.contains(new OMission(1,"user_firstname","user_lastname")){

System.out.println("true");}

else {

System.out.println("false");

}

I was expecting to get "true" but im always getting false

what's happening ?


Solution

  • You likely neglected to implement the crucial Object overrides for equals and hashCode.

    This issue is not specific to the OpenJFX class ObservableList. Any collection (list, set, map, etc.) that performs comparisons will depend on you writing an appropriate override for at least equals & possibly hashCode too. (Tip: Always override both or neither, never one alone.)

    Below is example code using a modified version of your code. By the way, you were missing a right-paren. Also, life is easier if you follow the Java naming conventions.

    For brevity, we use the new records feature in Java 16+. A record is a briefer way to write a class whose main purpose is to communicate data transparently and immutably. You merely need to declare the type and name of each member field. The compiler implicitly creates the constructor, getters, equals & hashCode, and toString. Those last three methods by default examine each and every member field‘s value.

    For simplicity we declared the record locally. You can just as well declare it nested or separate.

    package work.basil.example;
    
    import javafx.collections.*;
    
    public class App {
        public static void main ( String[] args ) {
            System.out.println ( "Hello World!" );
            App app = new App ();
            app.demo ();
        }
    
        private void demo () {
            record Person( int id , String firstName , String lastName ) { }
    
            ObservableList < Person > UserMission = FXCollections.observableArrayList ();
            Person p1 = new Person ( 1 , "Alice" , "Anderson" );
            UserMission.add ( p1 );
            if ( UserMission.contains ( new Person ( 1, "Alice" , "Anderson" ) ) ) {
                System.out.println ( "true" );
            } else {
                System.out.println ( "false" );
            }
        }
    }
    

    When run.

    Hello World!

    true

    If working with earlier versions for Java, or if a record is not appropriate to your situation, write a class similar to the following. Notice the methods equals & hashCode.

    package work.basil.example;
    
    import java.util.Objects;
    
    public final class Person {
        private final int id;
        private final String firstName;
        private final String lastName;
    
        public Person ( int id , String firstName , String lastName ) {
            this.id = id;
            this.firstName = firstName;
            this.lastName = lastName;
        }
    
        public int id () { return id; }
    
        public String firstName () { return firstName; }
    
        public String lastName () { return lastName; }
    
        @Override
        public boolean equals ( Object obj ) {
            if ( obj == this ) return true;
            if ( obj == null || obj.getClass () != this.getClass () ) return false;
            var that = ( Person ) obj;
            return this.id == that.id &&
                    Objects.equals ( this.firstName , that.firstName ) &&
                    Objects.equals ( this.lastName , that.lastName );
        }
    
        @Override
        public int hashCode () {
            return Objects.hash ( id , firstName , lastName );
        }
    
        @Override
        public String toString () {
            return "Person[" +
                    "id=" + id + ", " +
                    "firstName=" + firstName + ", " +
                    "lastName=" + lastName + ']';
        }
    }
    

    The issue of overriding equals/hashCode has been covered many many times already. Search to learn more.