0

Thanks a lot for all the answers/comments!

Apologize for the bad code sample I put in the original question. I was trying to simpify my question but apprently it ended up rather confusing.

I changed the code a little bit:

    Map<String, Boolean> map1 = new HashMap<>();
    map1.put("Yes", Boolean.FALSE);
    map1.put("No", Boolean.FALSE);

    Map<String, Map<String, List<String>>> map2 = new HashMap<>();
    List<String> list1 = Arrays.asList("Apple", "Peach");
    List<String> list2 = Arrays.asList("Pear", "Orange");
    Map<String, List<String>> innerMap = new HashMap<>();
    innerMap.put("fruit1", list1);
    innerMap.put("fruit2", list2);
    map2.put("Fruits", innerMap);
    map2.put("Vege", new HashMap<>());

    Optional<? extends Entry<String, ? extends Object>> optional = Stream
            .of(map1.entrySet().stream().filter(e -> e.getValue()).findFirst(),
                    map2.entrySet().stream().filter(entry -> entry.getValue().entrySet()
                            .stream()
                            .anyMatch(e -> e.getKey().equals("Fruit") && e.getValue().stream().anyMatch(
                                    i -> i.equals("Pear"))))
                            .findFirst())
            .filter(Optional::isPresent).map(Optional::get).findFirst();

    optional.orElse(new AbstractMap.SimpleEntry<>("NULL", null));

The I got the first error:

Cannot infer type arguments for AbstractMap.SimpleEntry<>

So I change the last line to:

   optional.orElse(new AbstractMap.SimpleEntry<String, Object>("NULL", null));

Then a new error pops up on orElse:

The method orElse(capture#4-of ? extends Map.Entry) in the type Optional> is not applicable for the arguments (AbstractMap.SimpleEntry)

As I understand, both Map have the same Key type but different Value types. The filter for each map is also different. So the returned would be an Optional with an Entry of String type Key but a generic type Value.

My original problem was I didn't know how to give a default value for this Optional since the Entry's Value type is generic (which I still don't know the answer now).

Inspired by @Ole, I refactored the code like this:

String result = Stream
            .of(map1.entrySet().stream().filter(e -> e.getValue()).map(Map.Entry::getKey).findFirst(), map2
                    .entrySet().stream().filter(entry -> entry.getValue().entrySet()
                            .stream()
                            .anyMatch(e -> e.getKey().contains("fruit") && e.getValue().stream().anyMatch(
                                    i -> i.equals("Pear"))))
                    .map(Map.Entry::getKey)
                    .findFirst())
            .filter(Optional::isPresent).map(Optional::get).findFirst().orElse("NULL");

System.out.println("result: " + result);

while I only collect the filtered Entry's Key into a stream and JAVA compiler seems working well. I get the exuection result as

result: Fruits

But it seems I'm still overcomplicating things here...

Sweden
  • 1
  • 1
  • `null` can't be inferred to `? extends Object&Serializable&Comparable>`. Maybe explicit cast will help – rkosegi Jul 17 '19 at 16:21

1 Answers1

0
    Map.Entry<String, ?> result = Stream.of(map1, map2)
            .flatMap(m -> m.entrySet().stream())
            .filter(e -> e.getKey().equals("Yes"))
            .findFirst()
            .orElse(new AbstractMap.SimpleEntry<>("NULL", null));
    System.out.println(result);

Output:

NULL=null

You were overcomplicating the handling of the Optional from findFirst. Don’t use isPresent nor get, orElse does everything for you.

You also don’t need type arguments for AbstractMap.SimpleEntry. Java infers <String, Object> from the arguments ("NULL", null).

I found it easier to start out from a stream of the maps so we only need to specify once what we are doing with the maps.

As an aside each of your maps only holds one entry. Your second put operation has an identical key, so overwrites the entry put in the first put call. So you could obtain the same result when leaving out the first call.

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
  • 2
    Speaking of overcomplicating, streaming over a `Map`, to apply `equals` on the keys, definitely belongs to this category, not to speak of turning an `O(1)` operation into an `O(n)` operation. `Object o = map1.getOrDefault("Yes", map2.get("Yes")); Map.Entry result = new AbstractMap.SimpleEntry<>(o == null? "NULL": "Yes", o);` would do the same, though, depending on what the OP actually wants to do with the result, it could be even simpler. There seems to be a fundamental misunderstanding on the OP’s side anyway, considering the `map1.put("No", true); map1.put("No", false);` etc. – Holger Jul 17 '19 at 17:39
  • Thanks for your answer!! I edited my original question with some more details. – Sweden Jul 18 '19 at 14:09