Ramesh KC Ramesh KC - 1 month ago 9
Java Question

Predicate generic method

I wrote a

Predicate
code that takes any
Object
and tests it for the following conditions:


  1. if
    Object
    type is
    String
    and contains
    "k"
    then it should return true.

  2. if
    Object
    type is
    Integer
    and greater than
    100
    then it should return true.

  3. if
    Object
    type is
    Employee
    which is class and having salary of employee greater than
    60000
    , it should return true.



After writing that
Predicate
method I wrote the
remove
method that removes values from list according to
Predicate
method.

public class ConditionalRemove {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<String>(Arrays.asList("ramesh", "kushal", "suresh", "kc"));
System.out.println(conditionalRemove(list));
}

public static <T> List<T> conditionalRemove(ArrayList<T> list) {
ConditionCheck<T> cond = new ConditionCheck<>();
for (T t : list) {
if (cond.test(t)) {
list.remove(t);
}
}
return list;
}

static class ConditionCheck<T> implements Predicate<T> {
@Override
public boolean test(T t) {
if (t instanceof String) {
return (((String) t).contains("k"));
} else if (t instanceof Integer) {
return ((int) t > 100);
} else if (t instanceof Employee) {
return ((int) ((Employee) t).getSalary() < 60000);
}
return true;
}
}
}


After compiling this code I found
Exception in thread "main" java.util.ConcurrentModificationException

Answer

The issue is you are updating the list when you are iterating over that. The issue can be fixed by updating code as

public static <T> List<T> conditionalRemove(ArrayList<T> list) {
        ConditionCheck<T> cond = new ConditionCheck<>();
        Iterator it = list.iterator();
        while(it.hasNext())     
        {
            it.next();
            if (cond.test(t)) {
                it.remove();
            }
         }
        return list;
    }
Comments