Stream API 如何修改map中的key和value?

Stream API how to modify key and value in a map?

我有一张 String - Array 地图,看起来像这样

dishIdQuantityMap[43]=[Ljava.lang.String;@301d55ce
dishIdQuantityMap[42]=[Ljava.lang.String;@72cb31c2
dishIdQuantityMap[41]=[Ljava.lang.String;@1670799
dishIdQuantityMap[40]=[Ljava.lang.String;@a5b3d21

我需要做的是

  1. 创建一个新映射,其中键 - 只有从字符串中提取的数字,像这样 ( key -> key.replaceAll("\D+","");
  2. 值 - 像这样的数组中的第一个值 value -> value[0];
  3. 过滤一个数组,以便只有这个巴黎留在 value > 0

我花了一个小时尝试自己解决,但用 .collect(Collectors.toMap()); 方法失败了。

更新: 到目前为止我完成的代码。我过滤地图失败了。

HashMap<Long, Integer> myHashMap =  request.getParameterMap().entrySet().stream()
        .filter(e -> Integer.parseInt(e.getValue()[0]) > 0)
        .collect(Collectors.toMap(MapEntry::getKey, MapEntry::getValue));

您可以通过使用流和辅助 KeyValuePair class 来实现。 KeyValuePair 会很简单:

public class KeyValuePair {

    public KeyValuePair(String key, int value) {
        this.key = key;
        this.value = value;
    }
    
    private String key;
    private int value;
    
    //getters and setters
}

有了这个 class 你可以像下面这样使用流:

Map<String, Integer> resultMap = map.entrySet().stream()
            .map(entry -> new KeyValuePair(entry.getKey().replaceAll("Key", "k"), entry.getValue()[0]))
            .filter(kvp -> kvp.value > 0)
            .collect(Collectors.toMap(KeyValuePair::getKey, KeyValuePair::getValue));

在示例中,我并没有完全按照您需要的条件进行替换和过滤,但是,正如您所说的收集器有问题,您可能只需要调整当前的代码即可。

我按以下顺序解决了这个问题:

  • 过滤 条带 value[0] > 0 的条目。此步骤是您列表中的最后一步,但就性能而言,最好将此操作放在管道的开头。它可能会减少在执行 map() 操作期间必须创建的对象数量;
  • 更新条目。 IE。用 新条目 替换每个条目。请注意,此步骤不需要创建 自定义 class 来表示 key-value 对 AbstractMap.SimpleEntry has been with us for a while. And since Java 9 instead of instantiating AbstractMap.SimpleEntry we can make use of the static method entry() Map 接口;
  • 在地图中收集个条目。
    public static Map<Long, Integer> processMap(Map<String, String[]> source) {
        return source.entrySet().stream()
                .filter(entry -> Integer.parseInt(entry.getValue()[0]) > 0)
                .map(entry -> updateEntry(entry))
                .collect(Collectors.toMap(Map.Entry::getKey,
                                          Map.Entry::getValue));
    }
    private static Map.Entry<Long, Integer> updateEntry(Map.Entry<String, String[]> entry) {
        return Map.entry(parseKey(entry.getKey()), parseValue(entry.getValue()));
    }

解析 keysvalues 的逻辑被提取到单独的方法中以使代码更清晰。

    private static Long parseKey(String key) {
        return Long.parseLong(key.replaceAll("\D+",""));
    }
    private static Integer parseValue(String[] value) {
        return Integer.parseInt(value[0]);
    }
    public static void main(String[] args) {
        System.out.println(processMap(Map.of("48i;", new String[]{"1", "2", "3"},
                                            "129!;", new String[]{"9", "5", "9"})));
    }

输出

{48=1, 129=9}