Java 8 extract all keys from matching values in a Map

So, you want a personOutputList with all the selected persons, and a keys set with the keys for those selected persons?

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 keys set is explicitly made an updatable copy. If you don't need that, drop the copying of the key values:

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

You can also use foreach api provided in java8 under lambda's

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

Instead of iterating over all the entries of the Map for each Person, I suggest iterating over the Map once:

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 HashSet containing the elements of personOutputList, since contains for HashSet takes constant time.

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

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