Я хочу отменить сортировку потока, как показано ниже, но получаю ошибку времени компиляции как "The method sorted() in the type IntStream is not applicable for the arguments ((<no type> o1, <no type> o2) -> {})". Кто-нибудь может это исправить
IntStream.range(1, 100)
.filter(x -> x%2 != 0)
.sorted((o1,o2) -> -o1.compareTo(o2))
.forEach(System.out::println);




поскольку вы работаете с IntStream, у него есть только одна перегрузка метода отсортированный, и это естественный порядок (что имеет смысл).
вместо этого поместите поток из IntStream в Stream<Integer>, тогда этого должно хватить:
IntStream.range(1, 100)
.filter(x -> x % 2 != 0)
.boxed() // <--- boxed to Stream<Integer>
.sorted((o1,o2) -> -o1.compareTo(o2)) // now we can call compareTo on Integer
.forEach(System.out::println);
Однако, как упоминал @Holger в комментариях:
never use a comparator function like
(o1,o2) -> -o1.compareTo(o2). It is perfectly legal for acompareToimplementation to returnInteger.MIN_VALUE, in which case negation will fail and produce inconsistent results. A valid reverse comparator would be (o1,o2) -> o2.compareTo(o1)
Лучшим подходом было бы:
IntStream.range(1, 100)
.filter(x -> x % 2 != 0)
.boxed()
.sorted(Comparator.reverseOrder())
.forEachOrdered(System.out::println);
Зачем?
forEachOrdered (большой привет @Holger, чтобы он всегда напоминал мне)или, как предлагает @Holger, все это можно упростить до такой степени:
IntStream.range(0, 50)
.map(i -> 99-i*2)
.forEachOrdered(System.out::println);
Кстати, в JDK9, начиная с кода в вашем сообщении, вы можете сначала упростить его с помощью iterate, чтобы:
IntStream.iterate(1, i -> i <= 99, i -> i + 2)
.boxed()
.sorted(Comparator.reverseOrder())
.forEachOrdered(System.out::println);
При таком подходе мы можем избежать промежуточной операции фильтрации и увеличения до 2.
и, наконец, вы можете еще больше упростить его с помощью:
IntStream.iterate(99, i -> i > 0 , i -> i - 2)
.forEachOrdered(System.out::println);
При таком подходе мы можем избежать filter, boxed, sorted и др.
Когда мы используем обычные напоминания, никогда не используйте функцию компаратора, такую как (o1,o2) -> -o1.compareTo(o2). Для реализации compareTo совершенно законно возвращать Integer.MIN_VALUE, и в этом случае отрицание не удастся и даст противоречивые результаты. Допустимым обратным компаратором может быть (o1,o2) -> o2.compareTo(o1) или просто Comparator.reverseOrder(), как вы показали, который уже выполняет свою работу правильно. Кстати, я бы использовал не iterate, а IntStream.range(0, 50).map(i -> 99-i*2), который во многих случаях более эффективен.
@Holger очень признателен за обучение, как всегда. отредактирован с учетом ваших рекомендаций.
Если это ваш настоящий код, то может быть более эффективным использовать IntStream.iterate и генерировать числа от 99 до 0:
IntStream.iterate(99, i -> i - 1)
.limit(100)
.filter(x -> x % 2 != 0)
.forEachOrdered(System.out::println);
Как насчет простой утилиты, такой как:
private IntStream reverseSort(int from, int to) {
return IntStream.range(from, to)
.filter(x -> x % 2 != 0)
.sorted()
.map(i -> to - i + from - 1);
}
Кредиты: Стюарт Маркс для обратного использования.
Мне любопытно, зачем вам использовать потоки для чего-то подобного. Казалось бы, это только добавило кучу накладных расходов.