Обратный Сортировка потока - PullRequest
0 голосов
/ 13 декабря 2018

Я хочу выполнить обратную сортировку потока, как показано ниже, но получаю ошибку времени компиляции как "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);

Ответы [ 3 ]

0 голосов
/ 13 декабря 2018

Если это ваш реальный код, то может быть более эффективно использовать IntStream.iterate и генерировать числа от 99 до 0:

IntStream.iterate(99, i -> i - 1)
    .limit(100)
    .filter(x -> x % 2 != 0)
    .forEachOrdered(System.out::println);
0 голосов
/ 13 декабря 2018

Как насчет простых утилит, таких как:

private IntStream reverseSort(int from, int to) {
    return IntStream.range(from, to)
                    .filter(x -> x % 2 != 0)
                    .sorted()
                    .map(i -> to - i + from - 1);
}

Кредиты : Стюарт Маркс за оборотное использование .

0 голосов
/ 13 декабря 2018

Пояснение

, поскольку вы работаете с 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 в комментариях:

никогдаиспользуйте функцию сравнения, такую ​​как (o1,o2) -> -o1.compareTo(o2).Для реализации compareTo вполне законно возвращать Integer.MIN_VALUE, в этом случае отрицание завершится неудачей и приведет к противоречивым результатам.Действительным обратным компаратором будет (o1, o2) -> o2.compareTo (o1)

Предложения по улучшению вашего кода.JDK8

Лучшим подходом было бы:

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

кстати, в 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 и др.

...