0

I need to filter a list List<Map<String, String>> by value (if map have searched value, then map add to list) using streams. I'm trying to do this:

static Map<String, String> map1 = new HashMap<>();
static Map<String, String> map2 = new HashMap<>();
static Map<String, String> map3 = new HashMap<>();

static {
    map1.put("key", "value");
    map1.put("key2", "value2");

    map2.put("key3", "value3");
    map2.put("key2", "value2");

    map3.put("key3", "value3");
    map3.put("key4", "value4");
}

public static void main(String[] args) {
    List<Map<String, String>> list = new ArrayList<>();
    Map<String, String> resultMap = new HashMap<>();

    list.add(map1);
    list.add(map2);
    list.add(map3);

    List<Map<String, String>> result = list.stream()
            .flatMap(map -> map.entrySet().stream())
            .filter(value -> value.getValue().equals("value2"))
            .map(x -> resultMap.put(x.getKey(), x.getValue()))
            .collect(Collectors.toList());

}

For execution this code i have error: java: incompatible types: inference variable T has incompatible bounds equality constraints: java.util.Map lower bounds: java.lang.String

1
  • 1
    Does this approach work? If not, do you get an error? Or do you get an unexpected result? Which? Commented Sep 2, 2019 at 9:59

2 Answers 2

2

If you want all the Maps of the input List that contain the "value2" value to appear in the output List, you need:

List<Map<String, String>> result = 
    list.stream()
        .filter(map -> map.entrySet().stream().anyMatch (e->e.getValue().equals("value2")))
        .collect(Collectors.toList());

Or (as Eritrean commented):

List<Map<String, String>> result = 
    list.stream()
        .filter(map -> map.containsValue("value2"))
        .collect(Collectors.toList());
Sign up to request clarification or add additional context in comments.

2 Comments

Wouldn't it be sufficient to use map.containsValue? list.stream() .filter(map -> map.containsValue("value2")).collect(Collectors.toList());
If you want to use a Stream operation instead of the straight-forward map.containsValue("value2"), it would still be more natural to use map.values().stream().anyMatch("value2"::equals) instead of streaming over the entrySet() and having to call getValue() for each entry.
0

Another quick solution is removeIf function. Has the advantage of reusing the same list object.

 list.removeIf(map -> !map.containsValue("value2"));

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.