@SuppressWarnings("rawtypes")
    public static <T> List<T> topp(final Collection<? extends T> c, final int fromIndex, final int toIndex, final int n, final Comparator<? super T> cmp) {
        N.checkArgNotNegative(n, "n");

        if (n == 0) {
            return new ArrayList<>();
        } else if (n >= toIndex - fromIndex) {
            if (fromIndex == 0 && toIndex == c.size()) {
                return new ArrayList<>(c);
            } else {
                final List<T> res = new ArrayList<>(toIndex - fromIndex);
                final Iterator<? extends T> iter = c.iterator();
                T e = null;

                for (int i = 0; i < toIndex && iter.hasNext(); i++) {
                    e = iter.next();

                    if (i < fromIndex) {
                        continue;
                    }

                    res.add(e);
                }

                return res;
            }
        }

        final Comparator<Indexed<T>> comparator = cmp == null ? (Comparator) new Comparator<Indexed<Comparable>>() {
            @Override
            public int compare(final Indexed<Comparable> o1, final Indexed<Comparable> o2) {
                return N.compare(o1.value(), o2.value());
            }
        } : new Comparator<Indexed<T>>() {
            @Override
            public int compare(final Indexed<T> o1, final Indexed<T> o2) {
                return cmp.compare(o1.value(), o2.value());
            }
        };

        final Queue<Indexed<T>> heap = new PriorityQueue<>(n, comparator);

        if (c instanceof List && c instanceof RandomAccess) {
            final List<T> list = (List<T>) c;
            Indexed<T> indexed = null;
            T e = null;

            for (int i = fromIndex; i < toIndex; i++) {
                e = list.get(i);

                indexed = Indexed.of(e, i);

                if (heap.size() >= n) {
                    if (comparator.compare(heap.peek(), indexed) < 0) {
                        heap.poll();
                        heap.add(indexed);
                    }
                } else {
                    heap.offer(indexed);
                }
            }
        } else {
            final Iterator<? extends T> iter = c.iterator();
            Indexed<T> indexed = null;
            T e = null;

            for (int i = 0; i < toIndex && iter.hasNext(); i++) {
                e = iter.next();

                if (i < fromIndex) {
                    continue;
                }

                indexed = Indexed.of(e, i);

                if (heap.size() >= n) {
                    if (comparator.compare(heap.peek(), indexed) < 0) {
                        heap.poll();
                        heap.add(indexed);
                    }
                } else {
                    heap.offer(indexed);
                }
            }
        }

        final Indexed<T>[] arrayOfIndexed = heap.toArray(new Indexed[heap.size()]);

        N.sort(arrayOfIndexed, new Comparator<Indexed<T>>() {
            @Override
            public int compare(final Indexed<T> o1, final Indexed<T> o2) {
                return o1.index() - o2.index();
            }
        });

        final List<T> res = new ArrayList<>(arrayOfIndexed.length);

        for (int i = 0, len = arrayOfIndexed.length; i < len; i++) {
            res.add(arrayOfIndexed[i].value());
        }

        return res;
    }
@ SuppressWarnings ( "rawtypes" ) public static < T > List < T > topp ( final Collection < ? extends T > c , final int fromIndex , final int toIndex , final int n , final Comparator < ? super T > cmp ) { N . checkArgNotNegative ( n , "n" ) ; if ( n == 0 ) { return new ArrayList < > ( ) ; } else if ( n >= toIndex - fromIndex ) { if ( fromIndex == 0 && toIndex == c . size ( ) ) { return new ArrayList < > ( c ) ; } else { final List < T > res = new ArrayList < > ( toIndex - fromIndex ) ; final Iterator < ? extends T > iter = c . iterator ( ) ; T e = null ; for ( int i = 0 ; i < toIndex && iter . hasNext ( ) ; i ++ ) { e = iter . next ( ) ; if ( i < fromIndex ) { continue ; } res . add ( e ) ; } return res ; } } final Comparator < Indexed < T > > comparator = cmp == null ? ( Comparator ) new Comparator < Indexed < Comparable > > ( ) { @ Override public int compare ( final Indexed < Comparable > o1 , final Indexed < Comparable > o2 ) { return N . compare ( o1 . value ( ) , o2 . value ( ) ) ; } } : new Comparator < Indexed < T > > ( ) { @ Override public int compare ( final Indexed < T > o1 , final Indexed < T > o2 ) { return cmp . compare ( o1 . value ( ) , o2 . value ( ) ) ; } } ; final Queue < Indexed < T > > heap = new PriorityQueue < > ( n , comparator ) ; if ( c instanceof List && c instanceof RandomAccess ) { final List < T > list = ( List < T > ) c ; Indexed < T > indexed = null ; T e = null ; for ( int i = fromIndex ; i < toIndex ; i ++ ) { e = list . get ( i ) ; indexed = Indexed . of ( e , i ) ; if ( heap . size ( ) >= n ) { if ( comparator . compare ( heap . peek ( ) , indexed ) < 0 ) { heap . poll ( ) ; heap . add ( indexed ) ; } } else { heap . offer ( indexed ) ; } } } else { final Iterator < ? extends T > iter = c . iterator ( ) ; Indexed < T > indexed = null ; T e = null ; for ( int i = 0 ; i < toIndex && iter . hasNext ( ) ; i ++ ) { e = iter . next ( ) ; if ( i < fromIndex ) { continue ; } indexed = Indexed . of ( e , i ) ; if ( heap . size ( ) >= n ) { if ( comparator . compare ( heap . peek ( ) , indexed ) < 0 ) { heap . poll ( ) ; heap . add ( indexed ) ; } } else { heap . offer ( indexed ) ; } } } final Indexed < T > [ ] arrayOfIndexed = heap . toArray ( new Indexed [ heap . size ( ) ] ) ; N . sort ( arrayOfIndexed , new Comparator < Indexed < T > > ( ) { @ Override public int compare ( final Indexed < T > o1 , final Indexed < T > o2 ) { return o1 . index ( ) - o2 . index ( ) ; } } ) ; final List < T > res = new ArrayList < > ( arrayOfIndexed . length ) ; for ( int i = 0 , len = arrayOfIndexed . length ; i < len ; i ++ ) { res . add ( arrayOfIndexed [ i ] . value ( ) ) ; } return res ; }
The present order is kept in the result list.

@param c
@param fromIndex
@param toIndex
@param n
@param cmp
@return