mardi 18 juillet 2017

filter list with any combination of fields in java using if statement

Suppose that we have a class like Person

Person.java

public class Person{

    String lastName;
    String code;
    String name;
    int age;

    public Person(String lastName, String code, String name, int age) {
        this.lastName = lastName;
        this.code = code;
        this.name = name;
        this.age = age;
}
    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    public String getLastName() {
        return lastName;
    }

    public String getCode() {
        return code;
    }

    public String toString() {
        return String.format("Person(%s,%s,%s,%s)", name, lastName, code, age);
    }


}

suppose there is another class that creates a list of Person

FilterList.java

public class FilterList {

public static void main(String[] args) {
    List<Person> list = Arrays.asList(
            new Person("Oscar", "ali soltani", "15-01", 0x20),
            new Person("Reyes", "javan", "16-01", 0x30),
            new Person("Java", "javan", "18-01", 20),
            new Person("hamid", "javan", "18-01", 20)
    );

    int age = 0 ;
    String name = "";
    String code = "";
    String lname = "javan";
    for (Person p : list) {
        if (((Integer.toString(age).isEmpty() || age ==0) ? true :p.getAge() == age) 
                && (code.isEmpty() ? true : p.getCode().equals(code)) 
                &&(lname.isEmpty() ? true :p.getLastName().equals(lname))  && 
                (name.isEmpty() ? true :p.getName().equals(name))  ) {
            System.out.println(p);
        }
    }
}

}

again suppose that we want to filter the list of Person by each field or any combinations of fields, e.g. if the field name is available we get the result such as every person whose name equals the given name, for example,

name = "ali";

so you should write such code like

   for (Person p : list) {
        if(p.getName().equals(name)){
            System.out.println(p);
        }
    }

therefor the output goes like this

Person(hamid,javan,18-01,20)

if you want to filter the list on any field you should write the same code, using if statement and suitable getter method and parameter to check the equality. there are four fields in the class Person we should write four if statements for each one. On the other hand, if you want to filter the list on any combinations of field you should write as before. Remarkable that if there are 4 fields in the class Person we should write 4! different if like the code below to support every combination of fields :

        for (Person p : list) {
        if(p.getName().equals(name)){ // filter on name
            System.out.println(p);
        } else if(p.getLastName().equals(lname)){ //filter on lastname
            System.out.println(p);
        } else if(){ // rest of the field same as above
            .
            .
            .

        }else if(p.getName().equals(name) && p.getLastName().equals(lname)){
                //filter on name and lastname
                System.out.println(p);
        }
        // rest of the code for other combinations
        .
        .
        .
        else if(p.getName().equals(name) && 
                p.getLastName().equals(lname) && 
                p.getCode().equals(code) &&
                p.getAge() == age){
                //filter on all fields
                System.out.println(p);
        }
    }

For the conditions with the dozens of fields, this would be very difficult and prone to errors, N! different states for the class with N fields.

I solved this problem by using ? : operator combining it with the if statement and filter the list with any combination of filed only with one if

 for (Person p : list) {
        if (((Integer.toString(age).isEmpty() || age ==0) ? true :p.getAge() == age) 
                && (code.isEmpty() ? true : p.getCode().equals(code)) 
                &&(lname.isEmpty() ? true :p.getLastName().equals(lname))  && 
                (name.isEmpty() ? true :p.getName().equals(name))  ) {
            System.out.println(p);
        }
    }

and it work perfectly. Is there any better way to answer this question ?

Aucun commentaire:

Enregistrer un commentaire