Преобразовать и ключ, и значение Map.Entry за один вызов stream().map()

У меня есть Stream<Map.Entry<?, ?>> и его нужно преобразовать в Stream<Map.Entry<Material, Long>> (Material это enum)

Вот функции преобразования:

  • ? -> Material:
entry -> Material.getMaterial(entry.getKey().toString())
  • ? -> Long
entry -> entry.getValue() instanceof Number ?
                                ((Number) entry.getValue()).longValue() : defaultTimeout

Material.getMaterial(String) представляет собой получение значения из HashMap<String, Material>, следовательно может возвращать null. Так как далее я использую EnumMap - мне нужно отфильтровать Entry, содержащие не валидные строки.

(и еще, мне не нужно выбрасывать IllegalArgumentException если строка не валидна, нужно просто пропустить содержащий ее Entry, поэтому метод Enum::valueOf мне не подходит)


Сейчас я использую:

ImmutableMap<Material, Long> outMap = configuration.getMapList("path")
                .stream().flatMap(map -> map.entrySet().stream())
                .filter(entry -> Material.getMaterial(entry.getKey().toString()) != null)
                .collect(Maps.toImmutableEnumMap(entry -> Material.getMaterial(entry.getKey().toString()),
                        entry -> entry.getValue() instanceof Number ?
                                ((Number) entry.getValue()).longValue() : defaultValue));

С одной стороны, все не очень плохо - строки не меняются => хеш не вычисляется повторно (он кэшируется классом String), но мне все еще не нравится лишний HashMap::get.


Могу ли я как то преобразовать и ключ, и значение Entry одним вызовом Stream::map, потом отфильтровать лишь по Entry.getKey() != null и собрать Maps.toImmutableEnumMap(entry -> entry.getKey(), entry -> entry.getValue())?


P.S. я использую Java 8, поэтому метод Map::entry() мне недоступен


UPDATE

Я стал использовать AbstractMap.SimpleImmutableEntry в своем коде (в методе map просто создаем новый SimpleImmutableEntry и в его конструктор уже передаем результаты методов преобразований). Словами получается не очень, это лучше увидеть:

ImmutableMap<Material, Long> outMap = configuration.getMapList("path")
                .stream().flatMap(map -> map.entrySet().stream())
                .map(entry -> new AbstractMap.SimpleImmutableEntry<>(
                        Material.getMaterial(entry.getKey().toString()),
                        entry.getValue() instanceof Number ?
                                ((Number) entry.getValue()).longValue() : defaultValue
                )).filter(entry -> entry.getKey() != null)
                .collect(Maps.toImmutableEnumMap(AbstractMap.SimpleImmutableEntry::getKey, AbstractMap.SimpleImmutableEntry::getValue));

Будет ли это оптимальным решением (именно пересоздавание Entry), если в исходном Stream может быть до 463 значений?


Ответы (0 шт):