Collect stream with grouping, counting and filtering operations

后端 未结 3 1500
佛祖请我去吃肉
佛祖请我去吃肉 2021-02-13 19:23

I\'m trying to collect stream throwing away rarely used items like in this example:

import java.util.*;
import java.util.function.Function;
import static java.ut         


        
3条回答
  •  死守一世寂寞
    2021-02-13 19:48

    A while ago I wrote an experimental distinct(atLeast) method for my library:

    public StreamEx distinct(long atLeast) {
        if (atLeast <= 1)
            return distinct();
        AtomicLong nullCount = new AtomicLong();
        ConcurrentHashMap map = new ConcurrentHashMap<>();
        return filter(t -> {
            if (t == null) {
                return nullCount.incrementAndGet() == atLeast;
            }
            return map.merge(t, 1L, (u, v) -> (u + v)) == atLeast;
        });
    }
    

    So the idea was to use it like this:

    Set commonlyUsed = StreamEx.of(allWords).distinct(3).toSet();
    

    This performs a stateful filtration, which looks a little bit ugly. I doubted whether such feature is useful thus I did not merge it into the master branch. Nevertheless it does the job in single stream pass. Probably I should revive it. Meanwhile you can copy this code into the static method and use it like this:

    Set commonlyUsed = distinct(allWords.stream(), 3).collect(Collectors.toSet());
    

    Update (2015/05/31): I added the distinct(atLeast) method to the StreamEx 0.3.1. It's implemented using custom spliterator. Benchmarks showed that this implementation is significantly faster for sequential streams than stateful filtering described above and in many cases it's also faster than other solutions proposed in this topic. Also it works nicely if null is encountered in the stream (the groupingBy collector doesn't support null as class, thus groupingBy-based solutions will fail if null is encountered).

提交回复
热议问题