2016-07-31 3 views
8

Я пытаюсь узнать о потоках и столкнулся с проблемой: Я хочу получить минимальное значение списка и назначить его переменной int. Для этого я сделал следующее:Java 8 streams "ifPresent"

List<Integer> list = new ArrayList<>(); 
    list.add(1); 
    list.add(2); 
    list.add(3); 
    int smallest = list.stream().min(Integer::compareTo).get(); 
    System.out.println(smallest); 

Это хорошо работает, и я получаю 1 в результате. Проблема заключается в том, что IDE выдает предупреждение о вызове Optional.get перед проверкой на .isPresent. Чтобы исправить это я использовал несколько иной метод ifPresent и попытался следующее:

int smallest = list.stream().min(Integer::compareTo).ifPresent(integer -> integer); 

К сожалению, это не работает, так как я получаю предупреждение: Bad return type in Lambda, Integer cannot be converted to void. Мой вопрос наконец: Как я могу присвоить значение мин до переменная int smallest С проверкой ifPresent?

+1

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

+1

'ifPresent' берет' Consumer' как свой аргумент, который потребляет входное значение и ничего не возвращает. –

ответ

6

Stream#min возвращение Optional результата, потому что в общем потоке может быть пустым, так что не может быть минимальное значение.

Optional<Integer> minimal = list.stream().min(Integer::compareTo); 

Чтобы получить значение из Опционно вам нужно иметь какое-то значение FALLBACK

Integer absent = Integer.MIN_VALUE; 

Проще было бы использовать orElse

Integer smallest = minimal.orElse(absent); 

Немного больше будет isPresent

Integer smallest = minimal.isPresent() ? minimal.get() : absent; 
+0

поэтому метод orElse возвращает тип Integer, а не необязательный, как метод .min? –

+1

Да, в этом примере это будет 'Integer'. Обычно 'Optional ' может содержать значение любого типа 'T', поэтому' orElse' возвращает этот тип 'T' –

+0

Большое вам спасибо! –

7

Вот как я это сделать:

package lambdas; 

import java.util.ArrayList; 
import java.util.List; 

/** 
* Created by Michael 
* Creation date 7/31/2016. 
* @link https://stackoverflow.com/questions/38688119/java-8-streams-ifpresent 
*/ 
public class MinimumExample { 

    public static void main(String[] args) { 
     List<Integer> list = new ArrayList<>(); 
     int smallest = list.stream().min(Integer::compareTo).orElse(Integer.MIN_VALUE); 
     System.out.println(smallest); 
    } 
} 
+0

Если метод '.min' возвращает необязательный параметр, то метод' .orElse' должен возвращать целое число. Вызывает ли '.ORElse' метод' .get'? –

+0

Этот код работает и работает.Он был поддержан ответом, который вы приняли. Какой у Вас вопрос? – duffymo

1

Метод ifPresent принимает параметр Consumer<? super T>. Проще говоря, это должно быть действие без заявления return. Вы можете распечатать значение, если оно присутствует, например

[...].ifPresent(System.out::print); 

Но это не то, что говорит IDEA. Я думаю, вам просто нужно сохранить Option<Integer> экземпляр, а затем проверить его isPresent:

Optional<Integer> o = list.stream().min(Integer::compareTo); 
if (o.isPresent()) { 
    smallest = o.get(); 
} 

Конечно, есть более удобные способы с orElse:

smallest = o.orElse(Integer.MIN_VALUE); 

или с тройным оператором:

smallest = o.isPresent() ? o.get() : Integer.MIN_VALUE; 
Смежные вопросы