2015-02-07 5 views
1

У меня есть ArrayList и еще один int, который приходит с консоли. Я хочу найти самое близкое число, большее, чем int в списке, используя stream(). Почему это не работает:сравнение Целые числа, использующие .stream() в java

Scanner scn = new Scanner(System.in); 
int numOfRows = scn.nextInt(); 
int nextNumber = scn.nextInt(); 
for (int i = 0; i < numOfRows; i++) { 
    String[] input = scn.nextLine().split(" "); 
    ArrayList<Integer> nums = new ArrayList<>(); 
    for (int j = 0; j < input.length; j++) { 
     nums.add(Integer.parseInt(input[j])); 
    } 
    nextNumber = nums.stream().filter(x -> x > nextNumber).findFirst(); 
    System.out.println(nextNumber); 
} 
+1

Вы забыли сообщить нам сообщение об ошибке компилятора (этот код не компилируется). – Seelenvirtuose

+0

Вам необходимо отсортировать список фильтров или применить к нему минимальную() операцию. findFirst() не является самым близким, но первым числом, которое больше, чем nextNumber. – eckes

ответ

3

Ваша непосредственная задача тривиальна исправить:

Optional<Integer> oi = nums.stream() 
          .filter(x -> x > nextNumber) 
          .findFirst(); 
System.out.println(oi.isPresent()? "Found: "+oi.get() : "Not found"); 

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

OptionalInt oi = Stream.of(scn.nextLine().split(" ")) 
         .mapToInt(Integer::parseInt) 
         .filter(i -> i > nextNumber) 
         .min(); 
System.out.println(oi.isPresent()? "Found: "+oi.getAsInt() : "Not found"); 

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

+2

Затем вы также можете сохранить создание массива: 'Pattern.compile (" ") .splitAsStream (scn.nextLine()). MapToInt (Integer :: parseInt) ...' – Holger

+0

Да, отличная точка. И если OP действительно нуждался в семантике findFirst() ', это даже могло бы оценивать регулярное выражение для короткого замыкания. –

2

Если вы хотите, чтобы найти наименьшее число больше некоторой границы:

private int smallestLargerThan(int x, List<Integer> list) { 
    return list.stream().filter(n -> n > x).mapToInt(n -> n).min(); 
} 

.filter(n -> n > x) падает все значения меньше или равно x.

.mapToInt(n -> n) превращает Stream к IntStream, который необходим для следующей операции:

.min() возвращает наименьший элемент в IntStream. Поскольку поток в этой точке содержит только значения, превышающие x, возвращаемый элемент - это номер, который вы ищете.

Код, который вы отправили, не скомпилируется, потому что .findFirst() возвращает Optional<Integer>, а не Integer. Это также семантически неправильно, потому что первый элемент не обязательно самый маленький, поскольку ваш Stream не сортирован.

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