【问题标题】:Stream and filter a SortedMap流式传输和过滤 SortedMap
【发布时间】:2019-10-10 22:15:45
【问题描述】:

我确信这很简单,但由于某种原因,我没有得到我想要的。

我有一个SortedMap<String, String> 值,我想通过它进行流式传输和过滤,并且只保存一些值。

例如:

    SortedMap<String, String> input = new TreeMap<>();
    values.put("accepted.animal", "dog");
    values.put("accepted.bird", "owl");
    values.put("accepted.food", "broccoli");
    values.put("rejected.animal", "cat");
    values.put("rejected.bird", "eagle");
    values.put("rejected.food", "meat");

我只想保留键中包含“接受”的值并删除其他所有值。

所以,结果是:

{accepted.animal=dog, accepted.bird=owl, accepted.food=broccoli}

如何通过地图流式传输并过滤除包含“已接受”的键之外的所有内容?

这是我尝试过的:

private SortedMap<String, String> process(final Input input) {
    final SortedMap<String, String> results = new TreeMap<>();

    return input.getInputParams()
                .entrySet()
                .stream()
                .filter(params -> params.getKey().contains("accepted"))
                .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
} 

但由于“无法从静态上下文引用非静态方法”而失败。

【问题讨论】:

    标签: java java-stream java-11 sortedmap


    【解决方案1】:

    您需要使用 Collectors.toMap 的另一个变体,以便您通过合并函数和供应商来收集作为 TreeMap 那里:

    return input.getInputParams()
            .entrySet()
            .stream()
            .filter(params -> params.getKey().startsWith("accepted")) // small change
            .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue,
                    (a, b) -> b, TreeMap::new));
    

    【讨论】:

    • 非常感谢!这正是我一直在寻找的。我在最初的问题中忘记问的一件事是 - 一旦params.getKey().startsWith(..) 为真,那么我想用“找到”替换“接受”。 .collect()之前可以做吗?
    • @AMagic 你可以map 条目,但最好避免在使用流时改变对象。
    • 我尝试map 条目,但我没有看到setKey 的任何选项。我正在尝试更改密钥,而不是值。 accepted.brid:owlfound.bird:owl 是否可以在上面的答案中添加一个 sn-p?
    • @AMagic 它应该类似于.filter(params -&gt; params.getKey().startsWith("accepted")).map(entry -&gt; new AbstractMap.SimpleEntry&lt;&gt;(entry.getKey().replace("accepted","found"), entry.getValue())).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (a, b) -&gt; b, TreeMap::new))
    【解决方案2】:

    最终,该方法无法编译,因为Collectors.toMap() 返回Map,而方法签名要求返回类型为SortedMap

    我不知道误导性“静态上下文”错误消息背后的原因;但是当我尝试使用 Gradle 构建代码时,我会收到一条稍微更有帮助的消息。

    error: incompatible types: inference variable R has incompatible bounds .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); ^ equality constraints: Map<K,U> lower bounds: SortedMap<String,String>,Object

    您可能想要接受Supplier&lt;Map&gt;Collectors.toMap() 的重载版本,以便您可以提供SortedMap 用于输出。

    【讨论】:

    • 谢谢 jaco0646。我不知道为什么我会收到误导性的错误消息。但我明白你在说什么。按照 Naman 的建议,我确实重载了 Collectors.toMap()。我已经问了一个错过的问题。一旦params.getKey().startsWith(..) 为真,那么我想replace "accepted" with "found"。 .collect()之前可以做吗?
    猜你喜欢
    • 2017-09-08
    • 1970-01-01
    • 2021-05-05
    • 1970-01-01
    • 1970-01-01
    • 2014-10-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多