简体   繁体   中英

How to give default value for a optional with generic type in JAVA

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...

    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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM