Java 8从Map

时间:2018-03-16 21:24:33

标签: java lambda java-8 java-stream

我对Java8比较陌生,我有一个场景,我需要从Map中检索与对象匹配的所有键。

想要知道是否有办法获取所有密钥而无需再次从列表中重复它们。

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()));
}

4 个答案:

答案 0 :(得分:9)

inputMap.entrySet() 
        .stream()
        .filter(entry -> personOutputList.contains(entry.getValue()))
        .map(Entry::getKey)
        .collect(Collectors.toCollection(HashSet::new))

答案 1 :(得分:6)

你也可以在lambda的

下使用java8中提供的 foreach api

以下是主要方法的代码:

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);
            }
        });
    }

答案 2 :(得分:5)

我建议迭代地图一次,而不是迭代每个Person的Map的所有条目:

Set<String> keys =
     inputMap.entrySet()
             .stream()
             .filter(e -> personOutputList.contains(e.getValue()))
             .map(Map.Entry::getKey)
             .collect(Collectors.toCollection(HashSet::new));

这仍然会导致二次运行时间(因为List.contains()具有线性运行时间)。如果您创建包含HashSet元素的personOutputList,则可以将其改善为整体线性运行时间,因为contains的{​​{1}}需要一段时间。

您可以通过更改

来实现这一目标
HashSet

List<Person> personOutputList = 
    personList.stream()
              .filter(p -> p.getFirstName().contains(inputCriteriaFirstName))
              .collect(Collectors.toList());

答案 3 :(得分:1)

那么,你想要一个personOutputList与所有选定的人一起,keys设置了那些选定人员的钥匙吗?

最佳(性能)选项是在搜索过程中不丢弃密钥,然后将结果拆分为单独的人员列表和密钥集。

像这样:

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());

keys集明确地成为可更新的副本。如果您不需要,请放弃复制键值:

Set<String> keys = tempMap.keySet();