10

I have a Map<String, List<String>>. I want to transform this map to a List after filtering on the map's key.

Example:

Map<String, List<String>> words = new HashMap<>();
List<String> aList = new ArrayList<>();
aList.add("Apple");
aList.add("Abacus");

List<String> bList = new ArrayList<>();
bList.add("Bus");
bList.add("Blue");
words.put("A", aList);
words.put("B", bList);

Given a key, say, "B"

Expected Output: ["Bus", "Blue"]

This is what I am trying:

 List<String> wordsForGivenAlphabet = words.entrySet().stream()
    .filter(x-> x.getKey().equalsIgnoreCase(inputAlphabet))
    .map(x->x.getValue())
    .collect(Collectors.toList());

I am getting an error. Can someone provide me with a way to do it in Java8?

4
  • Well, first off, what error are you getting? Commented Jul 18, 2017 at 21:15
  • 2
    Why don't you just use map.get(inputAlphabet.toUpperCase())? Commented Jul 19, 2017 at 3:37
  • 1
    @FedericoPeraltaSchaffner I assume because the Map might contains lower case letters also in general, this being just an example... Commented Jul 19, 2017 at 6:41
  • 1
    @Eugene Yes, I also think that this is a simplified example. I just commented so that OP has the chance to improve it. Commented Jul 19, 2017 at 14:35

4 Answers 4

17

Your sniplet wil produce a List<List<String>> not List<String>.

You are missing flatMap , that will convert stream of lists into a single stream, so basically flattens your stream:

List<String> wordsForGivenAlphabet = words.entrySet().stream()
    .filter(x-> x.getKey().equalsIgnoreCase(inputAlphabet))
    .map(Map.Entry::getValue)
    .flatMap(List::stream) 
    .collect(Collectors.toList());

You can also add distinct(), if you don't want values to repeat.

Sign up to request clarification or add additional context in comments.

6 Comments

I am getting "not-static method cannot be referenced from a static context" compilation error on .flatMap(List::stream) line
Is your map value of type List,Set? Here words is of Map<String, List<String>> type. What is your words collection type?
I have Map<String, Object>. I tried the same code as mentioned above and getting the compilation error.
This Map is coming from another class and I know the values will always be List<String> for a specific key.
I tried below and it worked. Is it because fo casting? List<String> l = map.entrySet().stream() .map(Map.Entry::getValue) .filter(c -> c instanceof Collection) .map(c -> (Collection<String>)c) .flatMap(Collection::stream) .collect(Collectors.toList());
|
4

Federico is right in his comment, if all you want is to get the values of a certain key (inside a List) why don't you simply do a get (assuming all your keys are uppercase letters already) ?

 List<String> values = words.get(inputAlphabet.toUpperCase());

If on the other hand this is just to understand how stream operations work, there is one more way to do it (via java-9 Collectors.flatMapping)

List<String> words2 = words.entrySet().stream()
            .collect(Collectors.filtering(x -> x.getKey().equalsIgnoreCase(inputAlphabet),
                    Collectors.flatMapping(x -> x.getValue().stream(), 
                          Collectors.toList())));

1 Comment

Very nice to use JDK 9 collector's new features
0

As was previously told after collect you will get List<List<String>> with only one or zero value in it. You can use findFirst instead of collect it will return you Optional<List<String>>.

2 Comments

When the map has "B" and "b" as keys, you get only one list.
Yes, I did not pay attention to equalsIgnoreCase, if it is importand my solution won't work properly.
0
List<String> items = words.entrySet().stream()
  .filter(entry -> entry.getKey().equals("B"))
  .flatMap(entry -> entry.getValue().stream())
  .collect(Collectors.toList());
  System.out.println(items);

1 Comment

While this code may answer the question, adding a bit of explanation would greatly benefit it, especially for future readers.

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.