2015-11-15 4 views
4

Я проходил через Streams Video, когда я сбился с толку о том, как Streams API дает ленивую оценку по принципу императива для цикла.Java 8 - ленивая оценка?

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

List<Integer> arr = Arrays.asList(1, 2, 3, 5, 4, 6, 7, 8, 9); 

    for (int i : arr) { 
     System.out.println(" Checking if is Greater: " + i); 
     if (i > 3) { 
      System.out.println("checking if is Even " + i); 
      if (i % 2 == 0) { 
       System.out.println(i * 2); 
       break; 
      } 
     } 
    } 

Здесь ожидаемый выход:

Checking if is Greater: 1 
Checking if is Greater: 2 
Checking if is Greater: 3 
Checking if is Greater: 5 
Checking if is Even 5 
Checking if is Greater: 4 
Checking if is Even 4 
8 

Теперь вот тот же самый код, используя Streams API:

arr.stream() 
     .filter(Lazy::isGreater) 
     .filter(Lazy::isEven) 
     .map(Lazy::doubleIt) 
     .findFirst(); 

Это тоже оценивает тот же путь. Итак, как filter() предоставляет что-то другое, которое мы не можем использовать с традиционными для петель?

+0

Не должны ли ваши утверждения 'println' находиться внутри соответствующих блоков' if'? – Clashsoft

+5

'filter' не предоставляет что-то другое, с которым вы не можете справиться для циклов. Это просто другой способ написания кода: императивный и функциональный. – Tunaki

+0

Учитывая, что Java завершала работу с момента ее первого выпуска, как с чего-то с тех пор предоставлялось нечто, чего нельзя было сделать раньше? – Cephalopod

ответ

3

Вот ключ: компонуемости

arr.stream() 
     .filter(Lazy::isGreater) 
     .filter(Lazy::isEven) 
     .map(Lazy::doubleIt) 
     .findFirst(); 

Это кажется безобидным, но это значение в настоящее время:

arr.stream() 
     .filter(Lazy::isGreater) 

Вы можете передать его в метод и построить на нем.

Что можно сделать с эквивалентом для цикла? Вы можете скопировать его в любое место, где бы вы его ни использовали. Это не сложная абстракция.

Кроме того, Stream делает как итерации и обработки абстрактных данных. Это может быть с пулами работников или с вилкой, или оно может идти в порядке, благоприятном для локализации ЦП или любого количества вещей. Вы больше не говорите JVM о том, как сделать что-то, что вы приближаетесь к тому, чтобы сказать ему, что делать, и дать понять, как это сделать.

+1

Спасибо, я как бы понял эту идею. Причина, по которой я задал этот вопрос, состояла в том, что большинство статей были посвящены этой ленивой оценке и тому, как потоки предоставляли эти промежуточные методы, которые были ленивы. Но они никогда не упоминали, почему это лучше, чем типичный императив для петель. – AgentX

+3

@AgentX ленивая оценка котельная. Он продается от функций, а не продается от того, что освобождает практикующего. Вместо того, чтобы продавать огненные цветы, мы должны сосредоточиться на продаже способности Марио бросать огненные шары. Легко забыть;) –

Смежные вопросы