У меня есть ArrayList и еще один int, который приходит с консоли. Я хочу найти самое близкое число, большее, чем int в списке, используя stream(). Почему это не работает:
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);
}
Ваша непосредственная проблема тривиальна:
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
и не нуждаетесь в автобоксе целых чисел на любом этапе и фактически получаете наименьшее число, удовлетворяющее критерию, а не первое.
Pattern.compile(" ") .splitAsStream(scn.nextLine()).mapToInt(Integer::parseInt) …
findFirst()
, это может даже привести к короткому замыканию в оценке регулярных выражений.
Если вы хотите найти наименьшее число, превышающее некоторую границу:
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
не сортирован.