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
我需要做的是
- 创建一个新映射,其中键 - 只有从字符串中提取的数字,像这样
( key -> key.replaceAll("\D+","");
- 值 - 像这样的数组中的第一个值
value -> value[0];
- 过滤一个数组,以便只有这个巴黎留在
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()));
}
解析 keys 和 values 的逻辑被提取到单独的方法中以使代码更清晰。
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}
我有一张 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
我需要做的是
- 创建一个新映射,其中键 - 只有从字符串中提取的数字,像这样
( key -> key.replaceAll("\D+","");
- 值 - 像这样的数组中的第一个值
value -> value[0];
- 过滤一个数组,以便只有这个巴黎留在
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 methodentry()
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()));
}
解析 keys 和 values 的逻辑被提取到单独的方法中以使代码更清晰。
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}