任何流式传输地图的方式,例如“(k,v)"而不是使用(条目)? [英] Any way to stream a map like "(k,v)" instead of working with (entry)?

查看:21
本文介绍了任何流式传输地图的方式,例如“(k,v)"而不是使用(条目)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

基本上我会寻找一种避免使用

Basically I look for a way to avoid working with

entry -> entry.getValue

entry -> entry.getKey

类似于 Map.forEach() 所做的.

如果我能找到一种方法来作为 map.stream().filter((k,v) -> )... 等等

If only I could get a way to work as map.stream().filter((k,v) -> )... and so on

这个接口好像叫BiConsumer.也许有一个转换器到 BiConsumer 或 Stream.generate() 以某种方式

It seems the interface is called BiConsumer. Perhaps with a converter to BiConsumer or a Stream.generate() someway

推荐答案

由于这是一个重复的问题,我将把一个完整的解决方案扔进戒指.它是一个 PairStream 类型,默认情况下是普通 Stream 的简单包装器(尽管作为 interface,替代方案是可能的).

Since this is a repeating question, I will throw a full solution into the ring. It’s a PairStream type that is by default a simple wrapper around an ordinary Stream (though, being an interface, alternatives are possible).

它侧重于提供方便的中间操作和那些不能通过调用 keys()values() 方法之一轻松执行的终端操作code>entries() 返回常规的单元素 Stream 并链接终端操作.例如,PairStream.from(map).filterValue(predicate).keys().findAny() 是获取映射值与谓词匹配的键的直接方法.filterValue 是一种方便的中间操作,而 keys 会返回一个普通的 Stream 允许对键进行任意终端操作.

It focuses on providing the convenient intermediate operations and those terminal operations which can not be easily performed by calling one of the methods keys(), values() or entries() to return to a conventional single-element Stream and chain a terminal operation. So for example, PairStream.from(map).filterValue(predicate).keys().findAny() is the straight-forward way to get a key for which the mapped value matches the predicate. filterValue is a convenience intermediate operation and keys turn back to an ordinary Stream allowing an arbitrary terminal operation for the keys.

一些例子

    Map<String,Integer> m=new HashMap<>();
    m.put("foo", 5);
    m.put("bar", 7);
    m.put("baz", 42);
    // {b=49, f=5}
    Map<Character,Integer> m2=PairStream.from(m)
      .mapKey(s->s.charAt(0))
      .toMap(Integer::sum);

    // foo bar
    String str=PairStream.from(m)
      .filterValue(i->i<30)
      .keys().sorted(Comparator.reverseOrder())
      .collect(Collectors.joining(" "));

    Map<String,Integer> map=new HashMap<>();
    map.put("muhv~", 26);
    map.put("kfool", 3);
    String str = PairStream.from(map)
      .sortedByValue(Comparator.naturalOrder())
      .flatMapToInt((s,i)->s.codePoints().map(c->c^i))
      .collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append)
      .toString();

这是完整的类(我没有测试所有的操作,但是大部分都是直截了当的):

Here is the complete class (I haven’t tested all operations, however most of it is straight-forward):

import java.util.*;
import java.util.function.*;
import java.util.stream.*;

public interface PairStream<K,V> {
    static <K,V> PairStream<K,V> from(Map<K,V> map) {
        return from(map.entrySet().stream());
    }
    static <K,V> PairStream<K,V> from(Stream<Map.Entry<K,V>> s) {
        return ()->s;
    }
    static <K,V> PairStream<K,V> from(Stream<K> s, Function<? super K, ? extends V> f) {
        return ()->s.map(k->new AbstractMap.SimpleImmutableEntry<>(k, f.apply(k)));
    }

    default PairStream<K,V> distinct() {
        return from(entries().distinct());
    }
    default PairStream<K,V> peek(BiConsumer<? super K, ? super V> action) {
        return from(entries().peek(e->action.accept(e.getKey(), e.getValue())));
    }
    default PairStream<K,V> skip(long n) {
        return from(entries().skip(n));
    }
    default PairStream<K,V> limit(long maxSize) {
        return from(entries().limit(maxSize));
    }
    default PairStream<K,V> filterKey(Predicate<? super K> mapper) {
        return from(entries().filter(e->mapper.test(e.getKey())));
    }
    default PairStream<K,V> filterValue(Predicate<? super V> mapper) {
        return from(entries().filter(e->mapper.test(e.getValue())));
    }
    default PairStream<K,V> filter(BiPredicate<? super K, ? super V> mapper) {
        return from(entries().filter(e->mapper.test(e.getKey(), e.getValue())));
    }
    default <R> PairStream<R,V> mapKey(Function<? super K,? extends R> mapper) {
        return from(entries().map(e->new AbstractMap.SimpleImmutableEntry<>(
            mapper.apply(e.getKey()), e.getValue()
        )));
    }
    default <R> PairStream<K,R> mapValue(Function<? super V,? extends R> mapper) {
        return from(entries().map(e->new AbstractMap.SimpleImmutableEntry<>(
            e.getKey(), mapper.apply(e.getValue())
        )));
    }
    default <R> Stream<R> map(BiFunction<? super K, ? super V,? extends R> mapper) {
        return entries().map(e->mapper.apply(e.getKey(), e.getValue()));
    }
    default DoubleStream mapToDouble(ToDoubleBiFunction<? super K, ? super V> mapper) {
        return entries().mapToDouble(e->mapper.applyAsDouble(e.getKey(), e.getValue()));
    }
    default IntStream mapToInt(ToIntBiFunction<? super K, ? super V> mapper) {
        return entries().mapToInt(e->mapper.applyAsInt(e.getKey(), e.getValue()));
    }
    default LongStream mapToLong(ToLongBiFunction<? super K, ? super V> mapper) {
        return entries().mapToLong(e->mapper.applyAsLong(e.getKey(), e.getValue()));
    }
    default <RK,RV> PairStream<RK,RV> flatMap(
            BiFunction<? super K, ? super V,? extends PairStream<RK,RV>> mapper) {
        return from(entries().flatMap(
            e->mapper.apply(e.getKey(), e.getValue()).entries()));
    }
    default <R> Stream<R> flatMapToObj(
            BiFunction<? super K, ? super V,? extends Stream<R>> mapper) {
        return entries().flatMap(e->mapper.apply(e.getKey(), e.getValue()));
    }
    default DoubleStream flatMapToDouble(
            BiFunction<? super K, ? super V,? extends DoubleStream> mapper) {
        return entries().flatMapToDouble(e->mapper.apply(e.getKey(), e.getValue()));
    }
    default IntStream flatMapToInt(
            BiFunction<? super K, ? super V,? extends IntStream> mapper) {
        return entries().flatMapToInt(e->mapper.apply(e.getKey(), e.getValue()));
    }
    default LongStream flatMapToLong(
            BiFunction<? super K, ? super V,? extends LongStream> mapper) {
        return entries().flatMapToLong(e->mapper.apply(e.getKey(), e.getValue()));
    }
    default PairStream<K,V> sortedByKey(Comparator<? super K> comparator) {
        return from(entries().sorted(Map.Entry.comparingByKey(comparator)));
    }
    default PairStream<K,V> sortedByValue(Comparator<? super V> comparator) {
        return from(entries().sorted(Map.Entry.comparingByValue(comparator)));
    }

    default boolean allMatch(BiPredicate<? super K,? super V> predicate) {
        return entries().allMatch(e->predicate.test(e.getKey(), e.getValue()));
    }
    default boolean anyMatch(BiPredicate<? super K,? super V> predicate) {
        return entries().anyMatch(e->predicate.test(e.getKey(), e.getValue()));
    }
    default boolean noneMatch(BiPredicate<? super K,? super V> predicate) {
        return entries().noneMatch(e->predicate.test(e.getKey(), e.getValue()));
    }
    default long count() {
        return entries().count();
    }

    Stream<Map.Entry<K,V>> entries();
    default Stream<K> keys() {
        return entries().map(Map.Entry::getKey);
    }
    default Stream<V> values() {
        return entries().map(Map.Entry::getValue);
    }
    default Optional<Map.Entry<K,V>> maxByKey(Comparator<? super K> comparator) {
        return entries().max(Map.Entry.comparingByKey(comparator));
    }
    default Optional<Map.Entry<K,V>> maxByValue(Comparator<? super V> comparator) {
        return entries().max(Map.Entry.comparingByValue(comparator));
    }
    default Optional<Map.Entry<K,V>> minByKey(Comparator<? super K> comparator) {
        return entries().min(Map.Entry.comparingByKey(comparator));
    }
    default Optional<Map.Entry<K,V>> minByValue(Comparator<? super V> comparator) {
        return entries().min(Map.Entry.comparingByValue(comparator));
    }
    default void forEach(BiConsumer<? super K, ? super V> action) {
        entries().forEach(e->action.accept(e.getKey(), e.getValue()));
    }
    default void forEachOrdered(BiConsumer<? super K, ? super V> action) {
        entries().forEachOrdered(e->action.accept(e.getKey(), e.getValue()));
    }

    default Map<K,V> toMap() {
        return entries().collect(
            Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
    }
    default Map<K,V> toMap(BinaryOperator<V> valAccum) {
        return entries().collect(
            Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, valAccum));
    }
}

这篇关于任何流式传输地图的方式,例如“(k,v)"而不是使用(条目)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆