3

I am iterating through a List of Hashmap to find the required HashMap object using the following code.

public static Map<String, String> extractMap(List<Map<String, String>> mapList, String currentIp) {
    for (Map<String, String> asd : mapList) {
        if (asd.get("ip").equals(currentIp)) {
            return asd;
        }
    }
    return null;
}

I was thinking about using Java 8 stream. This is the code I used to display the required object.

public static void displayRequiredMapFromList(List<Map<String, String>> mapList, String currentIp) {
    mapList.stream().filter(e -> e.get("ip").equals(currentIp)).forEach(System.out::println);
}

I couldn't get the required Map from the stream using following code

public static Map<String, String> extractMapByStream(List<Map<String, String>> mapList, String currentIp) {
    return mapList.stream().filter(e -> e.get("ip").equals(currentIp))
            .collect(Collectors.toMap(p -> p.getKey(), p -> p.getValue()));
}

This causes syntax error Type mismatch: cannot convert from Map to Map. What do I have to put here to get Map?

2
  • 1
    mapList.stream().filter(e -> e.get("ip").equals(currentIp)).findFirst() ... Note that this returns an Optional<Map ...> Commented Jan 12, 2018 at 10:54
  • 3
    Consider defining classes rather than nested collections. It gets hard to understand what a List<Map<Set<String>, Map<Integer, List<HttpClient>>>> is supposed to represent. Commented Jan 12, 2018 at 10:55

3 Answers 3

7

You don't want to .collect anything. You want to find the first map that matches the predicate.

So you should use .findFirst() instead of .collect().

toMap() is for building a Map from the elements in the stream.

But you don't want to do that, each element is already a Map.

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

4 Comments

if order is not needed, one might also use findAny()
I have accepted @Andrew's answer only because it completely translated my for loop method to stream with else null that is. Thank you.
@MuneebMirza That's fine. :) I recommend that you return the Optional<Map<String,String>> instead of .orElse(null). What are you doing with the null that is returned anyway?
@ChristofferHammarström so you are saying that I should instead return at findFirst()? Yes i think this makes more sense. Thanks :)
1

This will will work, the other examples without orElse() don't compile (at least they don't in my IDE).

mapList.stream()
    .filter(asd -> asd.get("ip").equals(currentIp))
    .findFirst()
    .orElse(null);

The only thing I would add as a suggestion is to return Collections.emptyMap(), this will save a null check in the calling code.

To get the code to compile without orElse you need to change the method signature to:

public static Optional<Map<String, String>> extractMap(List<Map<String, String>> mapList, String currentIp)

Comments

1

User this

    public static Map<String, String> extractMapByStream(List<Map<String, String>> mapList, String currentIp) {
        return mapList.stream().filter(e -> e.get("ip").equals(currentIp))
            .findFirst().get();
}

3 Comments

compiler error: Type Optional<Map<String, String>> is not assignable to type Map<String, String>
thats because findFirst() returns Optional and we have to call get() on it. I have updated the answer.
@RishikeshDhokare No, you don't blindly call .get() on an Optional if you're not sure that it's non-empty. That defeats the whole purpose of Optional.

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.