Java – Convert list to map and filter null keys

Using the Java 8 stream, I want to convert the list into a map as described in the solution of Java 8 list < V > into map < K, V > However, I want to filter to delete entries with certain keys (for example, if the key is empty) without converting the value to a key twice

For example, I can filter before collecting, for example

Map<String,Choice> result =
    choices.stream().filter((choice) -> choice.getName() != null).collect(Collectors.toMap(Choice::getName,Function.<Choice>identity());

In my example, the logic of obtaining the key is more complex than simply obtaining the field properties. I want to avoid executing the logic first in the filter and then in the collectors Execute logic in the keymapper function of tomap

How do I use the custom keymapper function to convert a list to a map and filter some values based on the new key?

Solution

This is the custom collector you want:

public class FilteredKeyCollector<T,K,V> implements Collector<T,Map<K,V>,V>> {

    private final Function<? super T,? extends K> keyMapper;
    private final Function<? super T,? extends V> valueMapper;
    private final Predicate<K> keyFilter;
    private final EnumSet<Collector.characteristics> characteristics;

    private FilteredKeyCollector(Function<? super T,? extends K> keyMapper,Function<? super T,? extends V> valueMapper,Predicate<K> keyFilter) {

        this.keyMapper = keyMapper;
        this.valueMapper = valueMapper;
        this.keyFilter = keyFilter;
        this.characteristics = EnumSet.of(Collector.characteristics.IDENTITY_FINISH);
    }

    @Override
    public supplier<Map<K,V>> supplier() {
        return HashMap<K,V>::new;
    }

    @Override
    public BiConsumer<Map<K,T> accumulator() {
        return (map,t) -> {
            K key = keyMapper.apply(t);
            if (keyFilter.test(key)) {
                map.put(key,valueMapper.apply(t));
            }
        };
    }

    @Override
    public BinaryOperator<Map<K,V>> combiner() {
        return (map1,map2) -> {
            map1.putAll(map2);
            return map1;
        };
    }

    @Override
    public Function<Map<K,V>> finisher() {
        return m -> m;
    }

    @Override
    public Set<Collector.characteristics> characteristics() {
        return characteristics;
    }
}

And use it:

Map<String,Choice> result = choices.stream()
    .collect(new FilteredKeyCollector<>(
                Choice::getName,// key mapper
                c -> c,// value mapper
                k -> k != null));   // key filter
The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>