Первое решение самое простое, но для него требуется промежуточное значение по умолчанию.
Hashtable<Integer, Hashtable<String, Integer>> h = new Hashtable<>();
h.put(1, new Hashtable<String, Integer>() {{put("firstKey", 3);}});
Integer intValue = h.getOrDefault(1, new Hashtable<>()).getOrDefault("firstKey", null);
System.out.println(intValue);
Решение на основе потоков:
Optional<Integer> firstValue = h.entrySet().stream()
.filter(e -> e.getKey().equals(1))
.flatMap(e -> e.getValue().entrySet().stream())
.filter(e -> e.getKey().equals("firstKey"))
.map(e -> e.getValue())
.findFirst();
firstValue.ifPresent(System.out::println);
Это может быть введен вспомогательный метод с Optional
.
private static <K,T> Optional<T> from(Map<K, T> from, K key) {
return (from.containsKey(key)) ? Optional.of(from.get(key)) : Optional.empty();
}
Тогда это выглядит более читабельно:
from(h, 1)
.flatMap(x -> from(x, "firstKey"))
.ifPresent(System.out::println);
Или добавьте другой метод, основанный на предыдущем:
private static <K, T> Function<Map<K, T>, Optional<T>> forKey(K key) {
return (Map<K, T> from) -> from(from, key);
}
И тогда его можно написать:
Optional.of(h)
.flatMap(forKey(1))
.flatMap(forKey("firstKey"))
.ifPresent(System.out::println);