2013-07-30 85 views
-1

我有兩個相同功能的實現,它們看起來如下所示。循環中的Java效率

private String mapToString(Map<String, String> map) 
     throws UnsupportedEncodingException 
{ 
    if(map.isEmpty()) 
    { 
     throw new IllegalArgumentException("Map cannot be empty"); 
    } 

    StringBuilder sb = new StringBuilder(); 

    for(Map.Entry<String, String> pair : map.entrySet()) 
    { 
     if(pair.getKey() == null) 
     {throw new IllegalArgumentException("Invalid parameter:" + 
       " Parameters key is null");} 

     if(pair.getValue() == null) 
     {throw new IllegalArgumentException("Invalid parameter:" + 
       " Parameters value is null");} 


     // Because the map cannot be empty and can be of arbitrary size it 
     // is it more efficient to append the _ at the end of each cycle and 
     // remove the extra _ when the string is done being built. 

     sb.append(URLEncoder.encode(pair.getKey(), "UTF-8")); 
     sb.append('-'); 
     sb.append(URLEncoder.encode(pair.getValue(), "UTF-8")); 
     sb.append('_'); 
    } 

    String result = sb.toString(); 

    // Remove the extra _ 
    return result.substring(0, result.length() - 1); 
} 

,第二個

private String mapToString(Map<String, String> map) 
     throws UnsupportedEncodingException 
{ 
    if(map.isEmpty()) 
    { 
     throw new IllegalArgumentException("Map cannot be empty"); 
    } 

    StringBuilder sb = new StringBuilder(); 

    for(Map.Entry<String, String> pair : map.entrySet()) 
    { 
     if(pair.getKey() == null) 
     {throw new IllegalArgumentException("Invalid parameter:" + 
       " Parameters key is null");} 

     if(pair.getValue() == null) 
     {throw new IllegalArgumentException("Invalid parameter:" + 
       " Parameters value is null");} 

     if(sb.length() != 0) 
     { 
      sb.append('_'); 
     } 
     sb.append(URLEncoder.encode(pair.getKey(), "UTF-8")); 
     sb.append('-'); 
     sb.append(URLEncoder.encode(pair.getValue(), "UTF-8")); 
    } 

    return sb.toString(); 
} 

這個方法的每個版本需要地圖上這是保證不爲空,並且根據它們創建的字符串的字符串。該字符串從鍵開始,然後是 - 然後是值。每個這些對由_分隔。

key1-value1_key2-value2_key3-value3_...... 

我的兩個選項來檢查,看看是否字符串是空的,而不是將_分離器和拯救自己創造末的子字符串。或者不要做一個檢查,在循環結尾附加_,然後使用一個子字符串去除多餘的_結果。

我很好奇哪一個對任意大的地圖來說效率更高。

+1

過早的優化?通常當你的代碼運行緩慢時,改進需要基本的算法改變,而不是像這樣的小改變。像這樣的優化只有在你的代碼運行緩慢時考慮*是有用的 - 而不是之前。 –

+1

你可以製作一個非常大的地圖,並[自己嘗試](http://stackoverflow.com/questions/180158/how-do-i-time-a-methods-execution-in-java)。 – ajp15243

+0

這可能是不成熟的優化,但兩者都非常易讀,所以我沒有看到嘗試使用最有效版本的問題。 – assylias

回答

3

這兩個實現之間的決定因素應該歸結爲可讀性。話雖如此,你使用substring的第一個實現將會更加昂貴,並且由於我看不到這兩者之間的可讀性差異,所以我寧願選擇第二個變體。另一種做法僅僅是使用boolean標誌,而不是檢查sb.length()

append = false; 

for (...) { 
    ... 

    if (append) { 
     sb.append('_'); 
    } 

    ... 

    append = true; 
}