1

I have a list of string and Map<String,String> where I need to replace values of a String with the values of map if list of elements are matching with key element of map.

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);
        }
    });
});

final string should be:

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

Key11 should not be replaced as it is not there in the mylist.

How to do the same using map()/stream() etc. functionality of Java 8 instead of a forEach loop? I have a large no of string elements in list and map which I need to replace in the final string dynamically.

Oleg Cherednik
  • 17,377
  • 4
  • 21
  • 35
Pkdrc
  • 43
  • 1
  • 7
  • 2
    It looks like you're building an SQL statement from pure non-parametrized strings you receive from somewhere. If you don't know it yet, you may want to read about SQL injection – Matteo NNZ Jun 20 '21 at 20:05
  • You already asked this question here: https://stackoverflow.com/questions/68053753/how-to-iterate-a-map-to-replace-in-final-string – Mario Ishac Jun 20 '21 at 20:31
  • Does this answer your question? [how to iterate a map to replace in final string](https://stackoverflow.com/questions/68053753/how-to-iterate-a-map-to-replace-in-final-string) – JayC667 Jun 20 '21 at 22:09
  • I have tried the solutions in the above link. Bit I cannot make my string as AtomicReference. Stream.reduce() sample code is not working..can anyone please suggest how to use stream.reduce() in this case successfully – Pkdrc Jun 21 '21 at 02:45

2 Answers2

1

Try this.

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);

output:

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

Or you can also do like this.

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);
0
Set<String> keys = Set.of("key1", "key2", "key3", "key4");
Map<String, String> map = Map.of(
        "key1", "value1",
        "key2", "value2",
        "key11", "value11");
String sql = "Select * from table1 where key1='apple' and key2='mango' and key11='banana'";
String res = Arrays.stream(sql.split("\\b"))
                   .map(word -> keys.contains(word) ? map.getOrDefault(word, word) : word)
                   .collect(Collectors.joining());
Oleg Cherednik
  • 17,377
  • 4
  • 21
  • 35