2016-10-25 6 views
0

Я написал Predicate код, который принимает любые Object и тестирует его на следующих условиях:Predicate шаблонный метод

  1. если Object тип String и содержит "k", то он должен вернуть истинный.
  2. если Object тип Integer и больше 100, тогда он должен возвращать true.
  3. , если Object тип Employee который является классом и имеет оклад работника более 60000, он должен возвращать true.

После написания, что Predicate метод, который я написал remove метод, который удаляет значения из списка в соответствии с Predicate способом.

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; 
     } 
    } 
} 

После компиляции этого кода я нашел Exception in thread "main" java.util.ConcurrentModificationException

+0

вы удаляете из списка в то время как вы итерацию его (в 'conditionalRemove()' Для того, чтобы исправить, сделать копию списка и итерацию, что – nbokmans

+0

@nbokmans -. не надо - просто использовать итератор в явном виде. –

+1

Возможный дубликат [Iterating throug ha Collection, избегая ConcurrentModificationException при удалении в цикле] (http://stackoverflow.com/questions/223918/iterating-through-a-collection-avoiding-concurrentmodificationexception-when-re) –

ответ

2

Вопрос заключается в обновлении списка, когда вы итерацию по этому поводу. Проблема может быть исправлена ​​путем обновления кода в

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; 
    } 
+0

вместо 'it.remove (t)' Я написал 'it.remove()', которые работают для меня. –

+0

Переменная 't' не определена. – saka1029

2

Поскольку вы используете Java 8, функциональный подход будет создать новый отфильтрованный список:

public static <T> List<T> conditionalRemove(ArrayList<T> list) { 
    return list.stream() 
      .filter(new ConditionCheck<>()) 
      .collect(Collectors.toList()); 
} 

Вы можете даже заменить статический внутренний класс просто метод:

public static <T> List<T> conditionalRemove(ArrayList<T> list) { 
    return list.stream() 
      .filter(ConditionalRemove::test) 
      .collect(Collectors.toList()); 
} 

private static <T> boolean test(T t) { 
    // your predicate implementation... 
} 
1

Некоторые структуры данных бросает java.util.ConcurrentModificationException при их изменении во время итерации, для того, чтобы сделать это с успехом вам нужно использовать синхронизированная структура, такая как «CopyOnWriteArrayList», это ссылка на java doc

Надеюсь, это может вам помочь!

С уважением.

2

Не изобретайте колесо: Используйте Collection#removeIf():

public static <T> List<T> conditionalRemove(ArrayList<T> list) { 
    list.removeIf(new ConditionCheck<>()); 
    return list; 
} 

На одной линии, это вряд ли стоит усилий создать метод для вызова ... просто сделать вызов однолинейного в линии: .

public static void main(String[] args) { 
    List<String> list = new ArrayList<>(Arrays.asList("ramesh", "kushal", "suresh", "kc")); 
    list.removeIf(new ConditionCheck<>()); 
    System.out.println(list); 
} 
Смежные вопросы