Java8从映射中匹配的值中提取所有键

Java8从映射中匹配的值中提取所有键,java,lambda,java-8,java-stream,Java,Lambda,Java 8,Java Stream,我对Java8比较陌生,我有一个场景,需要从映射中检索与对象匹配的所有键 想知道是否有一种方法可以获取所有密钥,而无需再次从列表中重复它们 Person.java private String firstName; private String lastName; //setters and getters & constructor MAIN Class. String inputCriteriaFirstName = "john"; Map<String, Per

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

想知道是否有一种方法可以获取所有密钥,而无需再次从列表中重复它们

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()));
}
Person.java
私有字符串名;
私有字符串lastName;
//setter和getter&构造函数
主课。
字符串inputCriteriaFirstName=“john”;
Map inputMap=newhashmap();
Collection personCollection=inputMap.values();
List personList=新建ArrayList(personCollection);
List personOutputList=personList.stream()
.filter(p->p.getFirstName().contains(inputCriteriaFirstName))
.collect(Collectors.toList());
//下面有更好的方法吗??
Set keys=new HashSet();
for(个人:个人输出列表){
keys.addAll(inputMap.entrySet().stream().filter(entry->Objects.equals(entry.getValue(),person))
.map(map.Entry::getKey).collect(collector.toSet());
}

我建议对地图进行一次迭代,而不是对每个
人的所有地图条目进行迭代:

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

Set personOutputSet=
personList.stream()
.filter(p->p.getFirstName().contains(inputCriteriaFirstName))
.collect(Collectors.toCollection(HashSet::new));

您还可以在lambda的支持下使用java8中提供的foreachapi

以下是主要方法的代码:

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);
            }
        });
    }
publicstaticvoidmain(){
字符串inputCriteriaFirstName=“john”;
Map inputMap=newhashmap();
Set keys=new HashSet();
inputMap.forEach((键,值)->{
if(value.getFirstName().contains(inputCriteriaFirstName)){
key.add(key);
}
});
}

那么,您想要一个包含所有选定人员的
人员输出列表
,以及一个包含这些选定人员的按键的
按键设置

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

像这样:

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

小挑剔:OP需要一个
哈希集
收集器。toSet
不能保证…@Eugene fair Enough同样,对于
e.getValue
返回空值的特定情况,我们在这里可能都是非常错误的,将来OP可能会有
列表(…)
个人输出列表
,因此,如果使用
空指针
,这将失败,而只是一个thought@Eugene对于我来说,在映射中使用空值没有什么意义,所以我认为没有必要考虑这种可能性。一般来说,我非常同意。但是OP使用
对象.equals(entry.getValue(),person)
…为什么要使用
收集器.toCollection(HashSet::new)
而不是问题中使用的
收集器.toSet()
。toSet
返回一个未定义的集(可能是不可变的),虽然OP确实需要一个
哈希集
,但我看不出OP确实需要
哈希集。我看到OP想要一个
(请参见
设置键
),并且OPs尝试为此创建一个
哈希集
,但我没有看到任何要求它必须是
哈希集;你认为下面Andreas提供的答案是什么?@Andreas我从
Set keys=new HashSet()推断出来的认为他希望保证是可变的
集合
。如果这是一个正确编码的方法,返回一个
集合
,我不会说这不是最时髦的方法,而是最便宜的方法,只有O(n)。@arthur最便宜的方法是使用
进行
循环。如果您只关心
O(n)
,那么也是
O(n)
,并且由于还提供了
personOutputList
,因此它只在内存复杂性方面有所不同。如果OP不需要它,可以很容易地将解决方案简化为一种“时髦”的方法,其复杂性与此
forEach
方法相同。
Set<Person> personOutputSet = 
    personList.stream()
              .filter(p -> p.getFirstName().contains(inputCriteriaFirstName))
              .collect(Collectors.toCollection(HashSet::new));
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);
            }
        });
    }
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());
Set<String> keys = tempMap.keySet();