Статьи

Потоковая передача через Карты с Java 8

отображение-потоки-малы В этой статье я покажу вам, как ускорить поток с открытым исходным кодом по стандартным картам 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);
Ссылка: Потоковая передача через Карты с Java 8 от нашего партнера JCG Эмиля Форслунда из блога Age of Java .