Является ли Collection.stream (). Filter (). ForEach () неэффективным по сравнению со стандартом для каждого цикла?


15

IntelliJ IDEA только что порекомендовал мне заменить следующий цикл for-each на вызов Java 8 forEach:

    for (Object o : objects) {
        if (o instanceof SomeObject) {
            doSomething();
        }
    }

Рекомендуемый вызов будет выглядеть так:

objects.stream().filter(o -> o instanceof SomeObject).forEach(o -> doSomething());

Если я не понимаю, как работает базовая функциональность Stream, мне кажется, что использование stream - это операция O (2n), а не операция O (n) для стандартного цикла for-each.


8
Почему вы думаете, что это O ^ 2? Фактически, потоки были изобретены специально для того, чтобы (а) позволить более приятный синтаксис и (б) не вводить дополнительные издержки. (Фактически, они часто уменьшают накладные расходы посредством ленивых вычислений.)
Килиан Фот

Основываясь на синтаксисе, похоже, что сначала выполняется итерация для фильтрации, а затем повторяется для отфильтрованных объектов во второй раз для запуска моего кода.
Миррана

6
Даже если бы это было так, это все равно было бы O (2 * N), то есть O (N), то есть линейное, а не квадратичное. Но на самом деле итерации чередуются друг с другом, и обе могут закончиться рано, если результат уже известен - в этом прелесть потоков. Определенно стоит потратить 15 минут на чтение потоков в Java 8; Как пишет Венкат Субраманиам, «лямбда-выражения - это наркотик,
являющийся

1
Кроме того: ваша петля является антипаттерном;)
Томас Джанк

1
@ThomasJunk Можете ли вы объяснить, как это антипаттерн? Я не знаком с этим.
Миррана

Ответы:


21

Потоки Java не проходят по вашей коллекции один раз для каждого оператора, несмотря на то, что подразумевается в синтаксисе. Он применяет всю цепочку к каждому элементу, по одному элементу за раз.

В вашем случае поток будет работать точно так же, как цикл. Возьмите элемент, сравните его с вашим предикатом, затем примените вашу операцию, затем перейдите к следующему элементу.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.