Потоковое API Java 8 Параллельная обработка - PullRequest
0 голосов
/ 16 мая 2018

У меня есть 2 комплекта

phraseSet содержит «Эйфелева башня», «Токийская башня»

wordSet содержит такие слова, как "эйфелева", "башня"

Как использовать параллельный поток Java 8 для обработки логики, например: 1. для каждого элемента в phraseSet токенизируйте его, посмотрите, существуют ли все токены в wordSet, если это так, добавьте этот элемент в новый набор с именем resultSet. В этом примере resultSet будет содержать «Эйфелеву башню»

Это легко сделать, если я использую традиционный цикл for, но я запутался при попытке использовать параллельный поток, который, я надеюсь, тоже быстрее, поскольку он обрабатывается параллельно.

Ответы [ 3 ]

0 голосов
/ 16 мая 2018

Вы можете использовать метод equals или containsAll здесь.

Set<String> resultSet = phraseSet.stream()
           .filter(s->wordSet.equals(Stream.of(s.split("\\s"))//wordSet.containsAll(...)
                  .collect(Collectors.toSet())))
           .collect(Collectors.toSet());
0 голосов
/ 16 мая 2018

Самое простое решение будет

Set<String> resultSet = phraseSet.stream()
    .filter(s -> wordSet.containsAll(Arrays.asList(s.split("\\s+"))))
    .collect(Collectors.toSet());

Вы можете превратить это в параллельную обработку, заменив stream() на parallelStream(), но вам потребуется довольно большой набор входных данных, чтобы получить выгоду от параллельной обработки.

Обратите внимание, что это простое решение может выполнять ненужную работу, если у вас много несоответствующих фраз, поскольку оно создаст все подстроки перед проверкой, содержатся ли они в wordSet. Решение типа Flown будет откладывать создание подстрок, поэтому его можно пропустить при обнаружении слова, не содержащегося в wordSet (также известного как короткое замыкание). Еще одним улучшением производительности было бы перемещение создания Pattern из обработки потока и его повторное использование (Pattern также создается за сценой при использовании метода, подобного String.split, как в приведенном выше решении).

Pattern whiteSpace = Pattern.compile("\\s+");
Predicate<String> inWordSet = wordSet::contains;
Set<String> resultSet = phraseSet.stream()
    .filter(phrase -> whiteSpace.splitAsStream(phrase).allMatch(inWordSet))
    .collect(Collectors.toSet());
0 голосов
/ 16 мая 2018

A filter и allMatch будет достаточно:

Set<String> phrases = new HashSet<>(Arrays.asList("eifel tower", "tokyo tower"));
Set<String> words = new HashSet<>(Arrays.asList("eifel", "tower"));
Pattern delimiter = Pattern.compile("\\s+");

Set<String> resultSet = phrases.parallelStream().filter(
    phrase -> delimiter.splitAsStream(phrase).allMatch(words::contains)
).collect(Collectors.toSet());
...