繁体   English   中英

删除 HashMap 中包含的列表项

[英]Deleting items the Lists contained within a HashMap

我有一个Hashmap<Long, List<Foo>> myMap 我想从任何List<Foo>中删除一个项目,其中Foo.key等于分配给key变量的值。

有没有用流来做到这一点的好方法? 我正在使用以下代码删除该项目,这对我来说似乎不是最好的:

for (List<Foo> l : myMap.values()) {
   for (Foo f : l) {
      if (f.getKey().equals(key)) {
         l.remove(f);
         break;
      }
   }
}

可能有多种方法可以做到这一点。 这是一个:

myMap.values().forEach(list->list.removeIf(foo -> Objects.equals(foo.getKey(), key)));

这个想法是 go 在 map 中的每个列表上,并删除具有要删除的键的元素。

您拥有的代码实际上是完成此任务的最合适工具。

既然需要修改map的内容,那就意味着需要一个stream,会产生副作用。 Stream API 的文档不鼓励这样做。

但是您可以通过使用添加到Collection接口的removeIf()方法来增强您的代码Java-8

public static void removeFooWithKey(Map<Long, List<Foo>> myMap, 
                                    String key) {
    
    for (List<Foo> foos : myMap.values()) {
        foos.removeIf(foo -> foo.getKey().equals(key));
    }
}

最简单的方法是:

myMap.values().forEach(list -> list.removeIf(foo -> foo.getKey().equals(key)))

但是removeIf会删除此集合中满足给定谓词的所有元素。 它不等于您的初始代码。 可能如果您的集合包含唯一键并且您只需要删除一个 object removeIf会做一点开销并比较集合的所有元素。

解决方案 1. 按第一个匹配的索引删除

myMap.values().forEach(list -> IntStream.range(0, list.size()).filter(index -> key.equals(list.get(index).getKey())).findFirst().ifPresent(list::remove))

解决方案 2. 自己的 removeFirstIf 方法

myMap.values().forEach(list -> StreamUtils.removeFirst(list, foo -> key.equals(foo.getKey())));

public class StreamUtils {
    private StreamUtils() {

    }
    public static <T> T removeFirstIf(Iterable<? extends T> collection, Predicate<? super T> condition) {
        Objects.requireNonNull(collection);
        Objects.requireNonNull(condition);

        T value;

        final Iterator<? extends T> iterator = collection.iterator();
        while (iterator.hasNext()) {
            value = iterator.next();
            if (condition.test(value)) {
                iterator.remove();
                return value;
            }
        }

        return null;
    }
}

解决方案 3. 将您的结构更改为 Map<Long, Map<String, Foo>>
假设:如果您的 List 可能由唯一键组成,那么您可以将结构从Map<Long, List<Foo>>更改为Map<Long, Map<String, Foo>>
通过Key删除元素将简单快速:

Map<Long, Map<String, Foo>> myMapOfMaps = new HashMap<>();
myMapOfMaps.values().forEach(map -> map.remove(key));

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM