-1

Using this code :

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.List;
import java.util.stream.Collectors;

public class Replace
{

    public static void main(String args[]){
        Map<String , String> map = new HashMap<String , String>();
        map.put("eleven", "11");

        String str = "replace the 11";

        List<String> ls = Arrays.asList(str.split(" "));

        ls.stream().map(m -> map.entrySet().forEach(e -> m.replaceAll(m , e.getKey())));
    }

}

I'm attempting to replace occurrences of "11" in the String str with "eleven". So str should be converted to "replace the eleven".

But I'm receiving compiler error :

Multiple markers at this line
    - Type mismatch: cannot convert from Stream<Object> to 
     <unknown>
    - Cannot return a void result

How to replace occurrences of keys in map that match string values ?

blue-sky
  • 51,962
  • 152
  • 427
  • 752

1 Answers1

1

Your map is back to front - keys should be the digits:

Map<String , String> map = new HashMap<String , String>();
map.put("11", "eleven"); // etc

Then it's a one liner:

str = Arrays.stream(str.split(" "))
  .map(s -> map.getOrDefault(s, s))
  .collect(Collectors.joining(" "));

Because this code consumes exactly 1 space on the split and puts back exactly one space on the join, variable numbers of spaces between words are preserved.

Here's some test code to show that:

Map<String , String> map = new HashMap<>();
map.put("11", "eleven"); // etc
String str = "one two  three   11  foo";

str = Arrays.stream(str.split(" "))
  .map(s -> map.getOrDefault(s, s))
  .collect(Collectors.joining(" "));

System.out.println(str);

Output:

one two  three   eleven  foo

See this code running live here.

Bohemian
  • 412,405
  • 93
  • 575
  • 722
  • if the strings contain variable length spaces can this be accommodated ? Using str.split("(?<=;)|(?=;)" ? But how to include the amount of space when re-joining ? – blue-sky Mar 24 '16 at 18:21
  • @blue-sky You can't then. Not like this. See the linked question where the idea is not to split around the spaces but to iterate over the replacements and call `replaceAll`. – Tunaki Mar 24 '16 at 20:00
  • @blue this works with variable spaces already. Exactly 1 space is consumed by the split, and exactly 1 space is put back by the joining. When multiple spaces are encountered, the "word" processed by the stream will be a blank (zero length) string. – Bohemian Mar 24 '16 at 20:51
  • @Tunaki have you tried my code with multiple spaces? – Bohemian Mar 24 '16 at 20:52
  • @Bohemian I was refering to the *But how to include the amount of space when re-joining* comment by the OP. If you split around 1 or 2 spaces or tabs, you can't know when re-joining what to use. – Tunaki Mar 24 '16 at 20:54
  • @blue-sky I've posted some test code showing preservation of multiple spaces between words. – Bohemian Mar 24 '16 at 21:14