Каковы возможные проблемы с использованием собранного результата в промежуточных операциях? - PullRequest
3 голосов
/ 24 апреля 2020

Рассмотрим следующий сценарий, в котором одна из промежуточных операций заботится о том, какая из предыдущих операций прошла успешно.

// isSelected -> method that returns a boolean on whether the current source is selected
List<String> selectedSources = new ArrayList<>();
sources.stream()
    .map(source -> Pair.of(source, isSelected(source, selectedSources)))
    .filter(pair -> pair.isRight())
    .map(pair -> pair.getLeft())
    .collect(Collectors.toCollection(() -> selectedSources));

В этом сценарии мы не работаем по-настоящему, и мы используем результат терминала Сбор в один из промежуточных этапов. Это работает, но идет вразрез с некоторыми фундаментальными принципами потоков java и функционального программирования в целом. Существуют ли общие указания относительно того, является ли это хорошей практикой или ее следует избегать?

1 Ответ

2 голосов
/ 25 апреля 2020

Обычно использование .collect с существующей коллекцией не является хорошей практикой. Обычно вы должны собирать в новую коллекцию .

Хотя, если вы все еще хотите изменить существующую коллекцию (что может привести к проблемам параллелизма), вы можете использовать .forEach вместо:

List<String> selectedSources = new ArrayList<>();
sources.stream()
       .filter(source -> isSelected(source, selectedSources))
       .forEach(selectedSources::add);

Поскольку вы пишете «не совсем функциональный» код, модифицирующий существующую коллекцию, нет смысла заставлять подход Stream API здесь.

ИМХО, улучшено для l oop и вложенного оператора if может хорошо работать в вашем случае. Код более читабелен:

List<String> selectedSources = new ArrayList<>();
for (String source : sources) {
    if (isSelected(source, selectedSources)) {
        selectedSources.add(source);
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...