谓词通用方法

时间:2016-10-25 22:08:10

标签: java generics

我写了一个Predicate代码,它接受任何Object并在以下条件下对其进行测试:

  1. 如果Object类型为String并且包含"k",那么它应该返回true。
  2. 如果Object类型为Integer且大于100,则应返回true。
  3. 如果Object类型为Employee且类别且员工薪水大于60000,则应返回true。
  4. 在编写了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

4 个答案:

答案 0 :(得分: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;
    }

答案 1 :(得分: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...
}

答案 2 :(得分: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);
}

答案 3 :(得分:1)

某些数据结构会在迭代过程中修改它们时抛出java.util.ConcurrentModificationException,为了成功实现这一点,您需要使用同步结构,例如“CopyOnWriteArrayList”,这是java doc参考

希望这可以帮到你!

问候。