0

// The array of values is in the form { "var1", "val1", "var2", "val2",.. }

 public static String replaceMethod(String template, String... values) {
            String p = template;
            for (int i = 0; i < values.length; i += 2) {
                p = p.replace(values[i], values[i+1]);
            }

            return populatedTemplate;    
        }

This method replaces a set of sub-strings with respectives values in a string. Ex:- string => abcd sub-string array of values ["a","b","c","d"] It means replace 'a' with 'b' and 'b' with 'c'.

So, now comes the issue.

1.My above implementation replaces 'a' with 'b' in first loop and then in second loop, it replaces 'b' with 'c' , making final string as "cccd". But I want the out as "bccd". Replacement in series uses the previous replaced string to work further. Is there a way to parallel replace all the sub-strings in a more efficient way.

2.How can I implement above method using Map, instead of array (second argument of above method)? Is Map better, or above implementation is fine ?

tarun14110
  • 940
  • 5
  • 26
  • 57
  • To me it seems like the problem of removing the first element from an array......http://stackoverflow.com/questions/3663944/what-is-the-best-way-to-remove-the-first-element-from-an-array – Rahul Kumar May 12 '16 at 12:55
  • It is quite incoherent what you are trying to say. If `template = "abcd"` and `values = {"a","b","c","d"}` then the output is `bbdd` – dryairship May 12 '16 at 13:02
  • @Hackerdarshi if template - "abcd " and values ={"a","b","c","d"} , then a ->b and c->d , I am using alternate indices of array for key value pairs. – tarun14110 May 12 '16 at 13:06

3 Answers3

2

You better use a map and iterate over every character in template. This way you avoid multiple substitutions at the same index position.

String template = "abcd";
StringBuilder populatedTemplate = new StringBuilder();
HashMap<Character, Character> map = new HashMap<>();
map.put('a', 'b');
map.put('b', 'c');
for (int i = 0; i < template.length(); i++) {
    populatedTemplate.append(
            map.getOrDefault(template.charAt(i), template.charAt(i)));
}
System.out.println(populatedTemplate);

Some pro arguments of this solution compared to OPs posted solution.

  • avoid multiple substitutions at the same index position, replace in a first step a to b and in a second step b to c which would lead into an unexpected effective replacement of a to c
  • iterate only once over template
  • don't create for each replacement pair a new String object, as it would have been here p = p.replace(values[i], values[i+1]);
SubOptimal
  • 22,518
  • 3
  • 53
  • 69
  • thanks , this it what i am looking for. Could you please give some more pros of this implementation? One I can think of is, iteration over the template string in only once. But in my implementation, template string in iterated no_of_string times. – tarun14110 May 12 '16 at 13:21
  • 1
    @tarun14110 I added some more explanation. – SubOptimal May 12 '16 at 13:39
  • hey, thanks for this. Can you please answer this http://stackoverflow.com/questions/37217588/replace-multiple-sub-strings-in-a-string. Its related to this one. – tarun14110 May 13 '16 at 19:09
  • @tarun14110 I believe this is not relevant anymore. As you got already an answer from Nicolas. For me it does exactly what you want. – SubOptimal May 17 '16 at 05:49
0

In the particular case of your a to b, b to c and such comparisons, you can get the desired result by giving the values array in reverse order.

In a more general case, you could replace 'a' with '_b_', then 'b' with '_c_'... And so on, and finally remove all the underscores. Of course, is your template text contains underscores, you can choose another character that you know won't be there, and use it instead.

Łukasz
  • 8,555
  • 2
  • 28
  • 51
0

Go with the solution using Map instead of String array to avoid getting ArrayIndexOutOfBoundsException. for instance you will get exceptions with this call using String array:

replaceMethod("abcd", "a","b","c")

Using Map:

     public static String replaceMethodMap(String template, Map<String, String> map) {
     String p = template;
     for (String key : map.keySet()) {
         p = p.replace(key, map.get(key));
     }

     return p;    
 }
Vijay
  • 542
  • 4
  • 15