使用过滤器从地图中删除元素

时间:2014-07-23 19:15:25

标签: java rx-java

我在rx.Observable中有一个java.util.Map,我想过滤地图(根据给定的键删除一个元素)。

我目前的代码是命令式和功能性的混合,我希望在不调用isItemInDataThenRemove的情况下实现此目标。

public static Observable<Map<String, Object>> filter(Map<String, Object> data, String removeKey) {
    return Observable.from(data).filter((entry) -> isItemInDataThenRemove(entry,removeKey));
}

private static boolean isItemInDataThenRemove(Map<String, Object> data, String removeKey) {
    for (Map.Entry<String,Object> entry : data.entrySet()) {
        if(entry.getKey().equalsIgnoreCase(removeKey)) {
            System.out.printf("Found element %s, removing.", removeKey);
            data.remove(removeKey);
            return true;
        }
    }
    return false;
}

2 个答案:

答案 0 :(得分:2)

您提出的代码存在一个普遍问题,即它在对其进行操作时修改了基础流。这与non-interference的流的一般要求相冲突,并且在实践中通常意味着当使用带有移除底层容器中的对象的容器的流管道时,您将获得ConcurrentModificationException

在任何情况下(正如我昨天所了解到的),Collection类上有一个新的默认方法,它可以完全符合您的要求:

private static boolean isItemInDataThenRemove(Map<String, Object> data, String removeKey) {
    return data.entrySet().removeIf(entry -> entry.getKey().equalsIgnoreCase(removeKey));
}

答案 1 :(得分:0)

工作代码:

private static boolean isItemInDataThenRemove(Map<String, Object> data, String removeKey) {
    data.entrySet().stream().filter(entry ->
            entry.getKey().equalsIgnoreCase(removeKey)).forEach(entry -> {
        data.remove(entry.getKey());
    });
    return true;
}