В этой статье я покажу вам, как ускорить поток с открытым исходным кодом по стандартным картам Java, расширив интерфейс Stream до чего-то, называемого MapStream! Это дополнение поможет вам поддерживать ваши потоки конкретными и читаемыми даже в сложных сценариях. Надеемся, что это позволит вам продолжать потоковую передачу без преждевременного сбора результата.
Одной из самых больших функций в Java 8 была возможность потоковой передачи по коллекциям объектов. Добавив метод .stream () — в интерфейс Collection, каждая коллекция на языке Java была внезапно расширена с помощью этой новой возможности. Другие структуры данных, такие как Map-интерфейс, не реализуют метод, так как они не являются строго говоря коллекциями.
MapStream будет принимать два параметра типа, ключ и значение. Это также расширит стандартный интерфейс Stream, указав Map.Entry <K, V> в качестве параметра типа. Это позволит нам создавать MapStream непосредственно из любой карты Java.
1
2
3
|
public interface MapStream<K, V> extends Stream<Map.Entry<K, V>> { ... } |
Концепция полиморфизма говорит нам, что дочерний компонент может изменять тип возвращаемого значения метода переопределения, если новый тип возвращаемого значения является более конкретной реализацией старого возвращаемого типа. Мы будем использовать это при определении интерфейса MapStream, так что для каждой операции сцепления возвращается MapStream вместо Stream.
01
02
03
04
05
06
07
08
09
10
11
12
13
|
public interface MapStream<K, V> extends Stream<Map.Entry<K, V>> { @Override MapStream<K, V> filter(Predicate<? super Map.Entry<K, V>> predicate); @Override MapStream<K, V> distinct(); @Override MapStream<K, V> sorted(Comparator<? super Map.Entry<K, V>> comparator); ... } |
Некоторые операции по-прежнему должны возвращать обычный поток. Если операция изменит тип потокового элемента, мы не можем гарантировать, что новый тип будет Map.Entry. Однако мы можем добавить дополнительные методы для сопоставления типов с парами ключ-значение.
1
2
3
4
|
@Override <R> Stream<R> map(Function<? super Map.Entry<K, V>, ? extends R> mapper); <R> Stream<R> map(BiFunction<? super K, ? super V, ? extends R> mapper); |
В дополнение к функции, которая позволяет пользователю сопоставлять запись с чем-то другим, он или она также может сопоставлять пару «ключ-значение» с чем-то другим. Это удобно, конечно, но мы также можем добавить более конкретные операции отображения теперь, когда мы работаем с парами значений.
1
2
3
|
<R> MapStream<R, V> mapKey(BiFunction<? super K, ? super V, ? extends R> mapper); <R> MapStream<K, R> mapValue(BiFunction<? super K, ? super V, ? extends R> mapper); |
Разница не очень большая, но разница очевидна при использовании API:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
|
// With MapsStream final Map<String, List<Long>> map = ...; MapStream.of(map) .mapKey((k, v) -> k + " (" + v.size() + ")" ) .flatMapValue((k, v) -> v.stream()) .map((k, v) -> k + " >> " + v) .collect(System.out::println); // Without MapStream final Map<String, List<Long>> map = ...; map.entrySet().stream() .map(e -> new AbstractMap.SimpleEntry<>( e.getKey() + " (" + e.getValue().size() + ")" ), e.getValue() )) .flatMap(e -> e.getValue().stream() .map(v -> new AbstractMap.SimpleEntry<>(e.getKey(), v)) ) .map(e -> e.getKey() + " >> " + e.getValue()) .collect(System.out::println); |
- Полная реализация MapStream может быть найдена здесь . Если вас интересуют более интересные вещи, загляните на страницу Speedment Github . Веселого прослушивания!
Ссылка: | Потоковая передача через Карты с Java 8 от нашего партнера JCG Эмиля Форслунда из блога Age of Java . |