5

In Java 7 I have

Map<String, List<String>> m = new HashMap<String, List<String>>();
boolean result = false;
m.put("Name1", Arrays.asList("abc*1"));
m.put("Name2", Arrays.asList("abc@*1"));


for (Map.Entry<String, List<String>> me : m.entrySet()) {
    String key = me.getKey();
    List<String> valueList = me.getValue();
    if (key.equals("Name2"){
        System.out.print("Values: ");
        for (String s : valueList) {
            if(s.contains("@"){
                result = true;
            }
        }
    }
} 

How can I get în a bool result for Name2 if it contains @ using any match?

I tried using The following Code but I Don t know how to use IT for specific key

result = m.values().stream().anyMatch(v -> v.contains("@"))
2
  • 1
    Did you mean if(s.contains("@"))? (Double quotes, not doubled apostrophes) Commented Jun 6, 2018 at 10:14
  • 1
    You have If for if and '' (two apostrophes) instead of ". Is this code supposed to be compilable? Commented Jun 6, 2018 at 10:15

7 Answers 7

9

Do the following:

boolean result = m.getOrDefault("Name2", Collections.emptyList()).stream()
    .anyMatch(i -> i.contains("@"));

If the Map contains a correct key, check whether any of its element of the List as value contains the particular character. If the Map doesn’t contain the key, mock the empty Collection which doesn't contain anything at all and the result is evaluated automatically as false.

Edit: As @Michael suggested, using the Collections.emptyList() is a better choice than new ArrayList<>().

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

6 Comments

This is the best way to do it. Why iterate over all of the keys when most maps are specifically designed to have a O(1) get?
@Michael Java 9 offers an in-between solution: Stream.ofNullable(m.get("Name2")) .flatMap(List::stream) .anyMatch(i -> i.contains("@"))
@Holger That's sufficiently different as to be worthy of its own answer, don't you think?
@Michael it’s different code, but not a fundamentally different logic, so I wouldn’t add an answer consisting of a small code snippet only. You can add it as an alternative to your answer, if you wish.
@Michael I have no objections against all these answers, but I don’t want to add another one. By the way, I see a fundamental difference. There are answers doing a linear iteration over the map and there are answers which avoid that.
|
7

You can simply use m.get("Name2"), place the (nullable) result into an Optional and then use a mapping:

boolean result = Optional.ofNullable(m.get("Name2"))
    .map(l -> l.stream().anyMatch(s -> s.contains("@")))
    .orElse(false);

This is preferable to looping over the entry set, as HashMap.get is O(1) and iterating over the entry set is O(n).

2 Comments

the map should be .map(l -> l.stream().anyMatch(s -> s.contains("@")))
Better: Optional.ofNullable(m.get("Name2")) .filter(l -> l.stream().anyMatch(s -> s.contains("@"))) .isPresent()
2

Try this:

boolean result = m.entrySet().stream()
    .filter(e -> e.getKey().equals(Name2))
    .map(Map.Entry::getValue)
    .flatMap(List::stream)
    .anyMatch(s -> s.contains("@"));

Comments

2

What about

String name = "Name1";
boolean result= m.containsKey(name) && m.get(name).stream().anyMatch(a -> a.contains("@"));

Comments

1

Just add correct filter condition:

m.entrySet()
.stream()
.anyMatch(entry-> entry.getKey().equals(Name2) && 
   entry.getValue()
.stream()
.anyMatch(string -> string.contains("@"))
.getValue();

Comments

1

First you should filter by the required key, then you can use anyMatch to determine if the value of that key contains an element with a '@' character:

result = m.entrySet ()
          .stream ()
          .filter (e->e.getKey ().equals (Name2))
          .anyMatch (e->e.getValue ().stream ().anyMatch (s->s.contains ("@")));

Comments

1

create a stream from the entrySet() and then provide your criteria in the anyMatch:

result = m.entrySet()
          .stream()
          .anyMatch(v -> Objects.equals("Name2", v.getKey()) && 
               v.getValue().stream().anyMatch(s -> s.contains("@")));

or using getOrDefault:

result = m.getOrDefault("Name2", Collections.emptyList())
          .stream()
          .anyMatch(s -> s.contains("@"));

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.