It’s hard to say whether .sorted().limit((long) N).toArray() will get optimized in some cases (it’s implementation dependent but given Oracle’s current implementation, I wouldn’t expect it), but in this special case, the source stream is a stream of unknown size which makes optimizations even less likely.
If you want to be on the safe side, you may adapt this solution for getting the n maximum numbers of a stream efficiently. All you have to do is to reverse the order:
public static IntStream maxValuesDescending(IntStream source, int limit) { TreeMap<Integer,Integer> m=new TreeMap<>(Comparator.reverseOrder()); source.forEachOrdered(new IntConsumer() { int size, min=Integer.MIN_VALUE; public void accept(int value) { if(value<min) return; m.merge(value, 1, Integer::sum); if(size<limit) size++; else m.compute(min=m.lastKey(), (k,count)->count==1? null: count-1); } }); if(m.size()==limit)// no duplicates return m.keySet().stream().mapToInt(Integer::valueOf); return m.entrySet().stream().flatMapToInt(e->{ int value = e.getKey(), count = e.getValue(); return count==1? IntStream.of(value): IntStream.range(0, count).map(i->value); }); }
Then you can use it like
int[] arr = maxValuesDescending(in.lines().mapToInt(Integer::parseInt), N).toArray();
But you are not required to create an array as you can use arbitrary IntStream operations on the result. This solution will hold at most N values, even less if there are duplicates as it only holds distinct values and their count.
Integer.MIN_VALUEvalues, you can add a step to mapi -> (-i). (TheInteger.MIN_VALUEqualification is important, sinceInteger.MIN_VALUE == (- Integer.MIN_VALUE)).sorted()is anyway going to store them all in memory, in which case you may as well just get that array and read the N greatest elements.