2016-05-19 11 views
3

以下に2つの関数が定義されています。彼らはまったく同じ関数を実行します。すなわち、入力(サブストリングを置き換えたいテンプレート)と文字列値の配列(置換するキー値のペア、例:[subStrToReplace1、value1、subStrToReplace1、value2、.....] )置き換えられたStringを返します。文字列内の複数の部分文字列を置き換える、配列対HashMap

2番目の関数では、テンプレートの単語を繰り返し、ハッシュマップと次の単語に存在する場合は関連するキーを検索しています。単語を、値の中の他のキーで置き換えたい部分文字列に置き換える場合は、テンプレートを2回繰り返して処理する必要があります。それは私がやったことです。

どちらを使用する必要があり、その理由を知りたいですか?これらよりも優れた選択肢もあります。

第一機能

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

第二の機能

public static String populateTemplate2(String template, String... values) { 
    HashMap<String, String> map = new HashMap<>(); 
    for (int i = 0; i < values.length; i += 2) { 
     map.put(values[i],values[i+1]); 
    } 
    StringBuilder regex = new StringBuilder(); 
    boolean first = true; 
    for (String word : map.keySet()) { 
     if (first) { 
      first = false; 
     } else { 
      regex.append('|'); 
     } 
     regex.append(Pattern.quote(word)); 
    } 
    Pattern pattern = Pattern.compile(regex.toString()); 

    int N0OfIterationOverTemplate =2; 
    // Pattern allowing to extract only the words 
    // Pattern pattern = Pattern.compile("\\w+"); 
    StringBuilder populatedTemplate=new StringBuilder();; 

    String temp_template=template; 

    while(N0OfIterationOverTemplate!=0){ 
     populatedTemplate = new StringBuilder(); 
     Matcher matcher = pattern.matcher(temp_template); 
     int fromIndex = 0; 
     while (matcher.find(fromIndex)) { 
      // The start index of the current word 
      int startIdx = matcher.start(); 
      if (fromIndex < startIdx) { 
       // Add what we have between two words 
       populatedTemplate.append(temp_template, fromIndex, startIdx); 
      } 
      // The current word 
      String word = matcher.group(); 
      // Replace the word by itself or what we have in the map 
      // populatedTemplate.append(map.getOrDefault(word, word)); 

      if (map.get(word) == null) { 
       populatedTemplate.append(word); 
      } 
      else { 
       populatedTemplate.append(map.get(word)); 
      } 

      // Start the next find from the end index of the current word 
      fromIndex = matcher.end(); 
     } 
     if (fromIndex < temp_template.length()) { 
      // Add the remaining sub String 
      populatedTemplate.append(temp_template, fromIndex, temp_template.length()); 
     } 

     N0OfIterationOverTemplate--; 
     temp_template=populatedTemplate.toString(); 
    } 
    return populatedTemplate.toString(); 
} 

答えて

1

決定的に少なくとも2つの理由のための最初の1:

  1. 読みやすいと短いので、それは簡単ですエラーを起こしにくいので維持するために
  2. あなたは正規表現に頼っていないので、はるかに高速です。
0

最初の機能ははるかに明確で分かりやすくなっています。あなたが(プロファイラによって)かなりの時間がかかり、アプリケーションが遅くなることが分かっていない限り、私はそれを好むでしょう。次に、それを最適化する方法を理解することができます。

0

シンプルにすると複雑になるのはなぜですか?

単純な解決策が最も優れていることに注意してください。

FYIの場合、要素の数と奇数の場合、ArrayIndexOutOfBoundsExceptionが発生します。

public static String populateTemplate(String template, String... values) { 
     String populatedTemplate = template; 
     int nextTarget = 2; 
     int lastTarget = values.length - nextTarget; 

     for (int i = 0; i <= lastTarget; i += nextTarget) { 
      String target = values[i]; 
      String replacement = values[i + 1]; 
      populatedTemplate = populatedTemplate.replace(target, replacement); 
     } 
     return populatedTemplate; 
    } 

"良いプログラマは、人間が理解できるコードを書く":

私はこの改善を提案します。 Martin Fowler

関連する問題