从 Java/Guava 中的某些键的映射中获取所有值?

发布于 2024-11-02 11:00:15 字数 203 浏览 2 评论 0原文

有没有一种聪明的方法可以从给定某些键的映射中获取所有值?

我想要一个这样的方法:

public static <K, V> Collection<V> getAll(Map<K, V> map, Collection<K> keys)

或者已经是番石榴的方式?

Is there a smart way to get all Values from a Map given some Keys?

I would like a method like this:

public static <K, V> Collection<V> getAll(Map<K, V> map, Collection<K> keys)

or is already a guava way?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

携余温的黄昏 2024-11-09 11:00:15

这取决于您希望该方法如何工作。例如,keys 中不在 map 中的元素应该被忽略 A) 还是应该 B) 在返回值集合中表示为 null 还是 C) 应该是一个错误?还要考虑您是否需要实时视图或包含值的单独集合。

对于A,我的偏好是:

Collection<V> values = Collections2.transform(
    Collections2.filter(keys, Predicates.in(map.keySet()),
    Functions.forMap(map));

这将结果限制为映射中实际存在的键的值,并且应该相对有效,即使映射比您设置的键集大得多。想。当然,您可能希望将该结果复制到另一个集合中,具体取决于您想用它做什么。

对于 B,您可以使用 @Michael Brewer-Davis 的解决方案,但 Functions.forMap(map, null) 除外。

对于C,您首先要检查map.keySet().containsAll(keys),如果false则抛出错误,然后使用 @Michael Brewer-Davis 的解决方案...但请注意,除非您将结果复制到另一个集合中,否则从 map 中删除条目可能会导致代码出现 IllegalArgumentException在某个时刻使用返回的集合。

This depends on how you want the method to work. For example, should elements in keys that aren't in map A) just be ignored or should they B) be represented as null in the returned values collection or should that C) be an error? Also consider whether you want a live view or a separate collection containing the values.

For A, my preference would be:

Collection<V> values = Collections2.transform(
    Collections2.filter(keys, Predicates.in(map.keySet()),
    Functions.forMap(map));

This limits the result to values for keys that are actually in the map and should be relatively efficient as well, even if the map is much larger than the set of keys you want. Of course, you may want to copy that result in to another collection depending on what you want to do with it.

For B, you'd use @Michael Brewer-Davis's solution except with Functions.forMap(map, null).

For C, you'd first want to check that map.keySet().containsAll(keys) and throw an error if false, then use @Michael Brewer-Davis's solution... but be aware that unless you then copied the result in to another collection, removing an entry from map could cause an IllegalArgumentException for code using the returned collection at some point.

°如果伤别离去 2024-11-09 11:00:15

我同意skaffman的回答,只是不同意他的结论(我认为这比手动迭代更好)。

这里是拼写出来的:

public static <K, V> Collection<V> getAll(Map<K, V> map, Collection<K> keys) {
    return Maps.filterKeys(map, Predicates.in(keys)).values();
}

另外,这是一个非 Guava 版本(Java 8 或更高版本):

public static <K, V> Collection<V> getAll(Map<K, V> map, Set<K> keys) {
    return map.entrySet()
            .stream()
            .filter(e -> keys.contains(e.getKey()))
            .map(Map.Entry::getValue)
            .collect(Collectors.toList());
}

I agree with skaffman's answer, just not with his conclusion (I think this is better than manual iteration).

Here it is spelled out:

public static <K, V> Collection<V> getAll(Map<K, V> map, Collection<K> keys) {
    return Maps.filterKeys(map, Predicates.in(keys)).values();
}

Also, here's a non-Guava version (Java 8 or higher):

public static <K, V> Collection<V> getAll(Map<K, V> map, Set<K> keys) {
    return map.entrySet()
            .stream()
            .filter(e -> keys.contains(e.getKey()))
            .map(Map.Entry::getValue)
            .collect(Collectors.toList());
}
偏爱你一生 2024-11-09 11:00:15

我想您可以使用 Guava 的 Maps.filteredKeys() ,传入与您所需的键匹配的谓词,但这并不比手动迭代更好。

You could, I suppose use Guava's Maps.filteredKeys(), passing in a Predicate which matches your desired keys, but it's not really any better than manual iteration.

转身泪倾城 2024-11-09 11:00:15

使用番石榴:
Collections2.transform(keys, Functions.forMap(map));

Using guava:
Collections2.transform(keys, Functions.forMap(map));

作死小能手 2024-11-09 11:00:15

Java8 Streams:

keys.stream().map( map::get ).collect( Collectors.toList() );

或者如果您担心丢失键:

keys.stream().map( k -> map.getOrDefault( k, null ) ).filter(o -> o != null).collect( Collectors.toList() );

或者如果您需要多个线程来工作(很少见,请参阅@tkruse 评论):

keys.parallelStream().map( map::get ).collect( Collectors.toList() );

Java8 Streams:

keys.stream().map( map::get ).collect( Collectors.toList() );

Or if you're concerned about missing keys:

keys.stream().map( k -> map.getOrDefault( k, null ) ).filter(o -> o != null).collect( Collectors.toList() );

Or if you need multiple threads to work (rarely, see @tkruse comment):

keys.parallelStream().map( map::get ).collect( Collectors.toList() );
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文