How to get a range of items from stream using Java 8 lambda?

后端 未结 2 1973
一向
一向 2020-12-07 23:56

In a previous question [ How to dynamically do filtering in Java 8? ] Stuart Marks gave a wonderful answer, and provided several useful utilities to handle selection of topN

2条回答
  •  北荒
    北荒 (楼主)
    2020-12-08 00:37

    User skiwi already answered the first part of the question. The second part is:

    (2) How to get top items from top 10% to top 30% from a stream with certain amount of items....

    To do this, you have to use a similar technique as topPercent in my answer to the other question. That is, you have to collect the elements into a list in order to be able to get a count of the elements, possibly after some upstream filtering has been done.

    Once you have the count, then you compute the right values for skip and limit based on the count and the percentages you want. Something like this might work:

    Criterion topPercentFromRange(Comparator cmp, double from, double to) {
        return stream -> {
            List temp =
                stream.sorted(cmp).collect(toList());
            return temp.stream()
                       .skip((long)(temp.size() * from))
                       .limit((long)(temp.size() * (to - from)));
        };
    }
    

    Of course you will have to do error checking on from and to. A more subtle problem is determining how many elements to emit. For example, if you have ten elements, they are at indexes [0..9], which correspond to 0%, 10%, 20%, ..., 90%. But if you were to ask for a range from 9% to 11%, the above code would emit no elements at all, not the one at 10% like you might expect. So some tinkering with the percentage computations is probably necessary to fit the semantics of what you're trying to do.

提交回复
热议问题