首页 > 解决方案 > 在java8 steam中从map的键中附加一个匹配值的字符串

问题描述

我有一个字符串列表和 Map<String,String> 如果元素列表与地图的关键元素匹配,我需要用地图的值替换字符串的值。

List<String> mylist = Arrays.asList("key1", "key2", "key3", "key4");
Map<String, String> map2 = new HashMap<>();
map2.put("key1", "value1");
map2.put("key2", "value2");
map2.put("key11", "value11");
var classVar = new Object() {
    String sb = "";
};
classVar.sb = "Select * from table1 where key1='apple' and key2='mango' and key11='banana'";

mylist.forEach(e -> {
    map2.forEach((k, v) -> {
        if (e.equalsIgnoreCase(k)) {
            classVar.sb = classVar.sb.replaceAll(k, v);
        }
    });
});

最后的字符串应该是:

Select * from table1 where value1='apple' and value2='mango' and key11='banana'

Key11不应更换,因为它不存在于mylist.

如何使用Java 8 的map()/stream()等功能而不是forEach循环来做同样的事情?我在列表和映射中有大量字符串元素,我需要在最终字符串中动态替换它们。

标签: javajava-stream

解决方案


尝试这个。

List<String> mylist = Arrays.asList("key1", "key2", "key3", "key4");
Set<String> mylistLower = mylist.stream().map(String::toLowerCase).collect(Collectors.toSet());
Map<String, String> map2 = new HashMap<String, String>();
map2.put("key1", "value1");
map2.put("key2", "value2");
map2.put("key11", "value11");
String in = "Select * from table1 where key1='apple' and key2='mango' and key11='banana'";
String out = Pattern.compile(map2.keySet().stream()
    .filter(s -> mylistLower.contains(s.toLowerCase()))
    .map(s -> "\\b" + Pattern.quote(s) + "\\b")
    .collect(Collectors.joining("|")))
    .matcher(in)
    .replaceAll(m -> map2.get(m.group()));
System.out.println(out);

输出:

Select * from table1 where value1='apple' and value2='mango' and key11='banana'

或者你也可以这样做。

String out = map2.entrySet().parallelStream()
    .filter(e -> mylistLower.contains(e.getKey().toLowerCase()))
    .reduce(in, (s, e) -> s.replaceAll("\\b" + e.getKey() + "\\b", e.getValue()),
        (a, b) -> a);

推荐阅读