Java 8 从 Map 中的匹配值中提取所有键
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/49329728/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Java 8 extract all keys from matching values in a Map
提问by Srinivas Lakshman
I'm relatively new to Java8 and I have a scenario where I need to retrieve all the keys from the Map which matched with the objects.
我对 Java8 比较陌生,我有一个场景,我需要从 Map 中检索与对象匹配的所有键。
Wanted to know if there is a way to get all keys without iterating them from the list again.
想知道是否有办法获取所有键而无需再次从列表中迭代它们。
Person.java
private String firstName;
private String lastName;
//setters and getters & constructor
MAIN Class.
String inputCriteriaFirstName = "john";
Map<String, Person> inputMap = new HashMap<>();
Collection<Person> personCollection = inputMap.values();
List<Person> personList = new ArrayList<>(personCollection);
List<Person> personOutputList = personList.stream()
.filter(p -> p.getFirstName().contains(inputCriteriaFirstName ))
.collect(Collectors.toList());
//IS There a BETTER way to DO Below ??
Set<String> keys = new HashSet<>();
for(Person person : personOutputList) {
keys.addAll(inputMap.entrySet().stream().filter(entry -> Objects.equals(entry.getValue(), person))
.map(Map.Entry::getKey).collect(Collectors.toSet()));
}
采纳答案by Eugene
inputMap.entrySet()
.stream()
.filter(entry -> personOutputList.contains(entry.getValue()))
.map(Entry::getKey)
.collect(Collectors.toCollection(HashSet::new))
回答by Sahil Aggarwal
You can also use foreachapi provided in java8 under lambda's
您还可以在 lambda 下使用java8 中提供的foreachapi
Below is code for your main method :
以下是您的主要方法的代码:
public static void main() {
String inputCriteriaFirstName = "john";
Map<String, Person> inputMap = new HashMap<>();
Set<String> keys = new HashSet<>();
inputMap.forEach((key,value) -> {
if(value.getFirstName().contains(inputCriteriaFirstName)){
keys.add(key);
}
});
}
回答by Eran
Instead of iterating over all the entries of the Map for each Person, I suggest iterating over the Map once:
Person我建议迭代 Map 一次,而不是为 each迭代Map 的所有条目:
Set<String> keys =
inputMap.entrySet()
.stream()
.filter(e -> personOutputList.contains(e.getValue()))
.map(Map.Entry::getKey)
.collect(Collectors.toCollection(HashSet::new));
This would still result in quadratic running time (since List.contains()has linear running time). You can improve that to overall linear running time if you create a HashSetcontaining the elements of personOutputList, since containsfor HashSettakes constant time.
这仍然会导致二次运行时间(因为List.contains()具有线性运行时间)。如果您创建一个HashSet包含 的元素,您可以将其提高到整体线性运行时间personOutputList,因为containsforHashSet需要恒定的时间。
You can achieve that by changing
你可以通过改变来实现
List<Person> personOutputList =
personList.stream()
.filter(p -> p.getFirstName().contains(inputCriteriaFirstName))
.collect(Collectors.toList());
to
到
Set<Person> personOutputSet =
personList.stream()
.filter(p -> p.getFirstName().contains(inputCriteriaFirstName))
.collect(Collectors.toCollection(HashSet::new));
回答by Andreas
So, you want a personOutputListwith all the selected persons, and a keysset with the keys for those selected persons?
那么,您想要一个personOutputList包含所有选定人员的keys集合,以及一个包含这些选定人员的键的集合?
Best (for performance) option is to not discard the keys during search, then split the result into separate person list and key set.
最佳(为了性能)选项是在搜索期间不丢弃键,然后将结果拆分为单独的人员列表和键集。
Like this:
像这样:
String inputCriteriaFirstName = "john";
Map<String, Person> inputMap = new HashMap<>();
Map<String, Person> tempMap = inputMap.entrySet()
.stream()
.filter(e -> e.getValue().getFirstName().contains(inputCriteriaFirstName))
.collect(Collectors.toMap(Entry::getKey, Entry::getValue));
List<Person> personOutputList = new ArrayList<>(tempMap.values());
Set<String> keys = new HashSet<>(tempMap.keySet());
The keysset is explicitly made an updatable copy. If you don't need that, drop the copying of the key values:
该keys集合被明确地制作为可更新的副本。如果您不需要,请删除键值的复制:
Set<String> keys = tempMap.keySet();

