Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to sort an IntStream in reverse order

I'm reading in numbers from a .txt file using BufferedReader. I want to reverse the order of elements in this steam so that when they are collected they will be arranged from the highest to the lowest. I don't want to sort after the array has been built because I have no idea how many elements might be in it, I only need the highest N elements.

in = new BufferedReader(reader);
                int[] arr = in.lines()
                        .mapToInt(Integer::parseInt)
                        .sorted()
                        .limit((long) N)
                        .toArray();
like image 910
Aurumae Avatar asked Jun 09 '15 18:06

Aurumae


People also ask

How do I reverse a List in Java 8?

Collect and Reverse a List in Java. The first approach would be to collect() the stream into a list - and then use the Collections. reverse() method on the list, which reverses it in-place. Note: If you also want to sort the collection while reversing it, you can use the sorted(Comparator.


3 Answers

Try negating the values before sorting and negating (back to normal) after sorting:

in = new BufferedReader(reader);
int[] arr = in.lines()
              .mapToInt(Integer::parseInt)
              .map(i -> -i).sorted().map(i -> -i)
              .limit((long) N)
              .toArray();
like image 156
normanrz Avatar answered Oct 03 '22 01:10

normanrz


Because the reverse order is not the natural order, sorted() can't be used to sort in reverse order. If you avoid the IntStream, using a Stream<Integer> instead, then you can use a Collections.reverseOrder() to sort the stream in a reverse to the natural order. Then you can call mapToInt and convert to int[] at the end.

int[] arr = in.lines()
            .map(Integer::valueOf)  // Extract Integer, not int
            .sorted(Collections.reverseOrder())  // On Stream<Integer>
            .limit(N)
            .mapToInt(i -> i)       // map Integer to int
            .toArray();
like image 35
rgettman Avatar answered Oct 03 '22 02:10

rgettman


when using Instream, you are actually dealing with primitive, and your hands are tight (you are limited to natural ordering and you can't define custom comparator. You have two solutions:

  • stick with the primitive stream and come up with hacks like the one proposed by @normanrz

  • or you can convert to Integer (box) and use variety of solution like the one bellow (but be advised this boxing and unboxing might cause performance problems).

    int[] sortedArray = IntStream.of(costs).boxed()
                                  .sorted(Collections.reverseOrder())
                                  .mapToInt(value -> value.intValue()).toArray();
    
like image 44
Mr.Q Avatar answered Oct 03 '22 01:10

Mr.Q