简体   繁体   English

如何在Java 8流API中有条件地修改Map?

[英]How to conditionally modify a Map in Java 8 stream API?

I am trying to modify a Map 's keys based on conditional logic and struggling. 我试图根据条件逻辑和挣扎来修改Map的键。 I'm new to Java 8 streams API. 我是Java 8 Streams API的新手。 Let's say I have a map like this: 假设我有一张这样的地图:

Map<String, String> map = new HashMap<>();

map.put("PLACEHOLDER", "some_data1");
map.put("Google", "some_data2");
map.put("Facebook", "some_data3");
map.put("Microsoft", "some_data4");

When I would like to do is find the references of PLACEHOLDER and conditionally change that key to something else based on a boolean condition. 我想做的是找到PLACEHOLDER的引用,并根据布尔条件有条件地将该键更改为其他键。 I feel like it should be something like the below, but this doesn't even compile of course. 我觉得喜欢它应该下面的,但这并不甚至编译过程的。

boolean condition = foo();

map = map.entrySet().stream().filter(entry -> "PLACEHOLDER".equals(entry.getKey()))
        .map(key -> {
            if (condition) {
                return "Apple";
            } else {
                return "Netflix";
            }
        }).collect(Collectors.toMap(e -> e.getKey(), Map.Entry::getValue));

I found this question which kind of makes me think maybe I can't do this with Java 8 stream APIs. 我发现了这个问题 ,这让我觉得也许我无法使用Java 8流API做到这一点。 Hopefully someone better at this than me knows how to do this. 希望有比我更好的人知道如何做到这一点。 Ideone link if you want to play with it. Ideone链接,如果您想使用它。

You've filtered out all elements that aren't PLACEHOLDER . 您已经过滤掉了不是 PLACEHOLDER所有元素。 You need to add that filter logic to your map operation: 您需要将该过滤器逻辑添加到map操作中:

final Map<String, String> output = input.entrySet().stream()
        .map(e -> {
            if (!e.getKey().equals("PLACEHOLDER")) {
                return e;
            }
            if (condition) {
                return new AbstractMap.SimpleImmutableEntry<>("Apple", e.getValue());
            }
            return new AbstractMap.SimpleImmutableEntry<>("Netflix", e.getValue());
        }).collect(toMap(Map.Entry::getKey, Map.Entry::getValue));

But as you are guaranteed to only have a single instance of PLACEHOLDER in the Map , you can just do 但是由于可以保证在Map只有一个PLACEHOLDER实例,因此您可以

String placeholderData = input.remove("PLACEHOLDER");
if (placeholderData != null) {
    input.put(condition ? "Apple" : "Netflix", placeholderData);
}

If you really want to do it using Stream s, you just need to move the conditional logic to the collection phase, like that: 如果您确实想使用Stream来执行此操作,则只需将条件逻辑移至收集阶段,如下所示:

boolean condition = true;
map.entrySet().stream().collect(Collectors.toMap(
        entry -> mapKey(entry.getKey(), condition), Map.Entry::getValue
));

where: 哪里:

private static String mapKey(String key, boolean condition) {
    if (!"PLACEHOLDER".equals(key)) {
        return key;
    }
    if (condition) {
        return "Apple";
    } else {
        return "Netflix";
    }
}

However, the second part of Boris the Spider's answer using Map.remove and Map.put seems the best way to go. 但是,使用Map.removeMap.put 回答《蜘蛛侠鲍里斯》的第二部分似乎是最好的方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM