2017-07-25 102 views
4

下面的代碼工作,但我有SonarLint通知,因爲我在流中使用匿名類而不是lambda表達式,並且我看不到如何改進下面的代碼避免了通知:[SonarLint]:使這個匿名內部類lambda

Properties prop = new Properties(); 
Properties temp = new Properties(); 
//... add some values and keys in prop and temp 

prop.putAll(temp.entrySet().stream() 
    .filter(entry -> !prop.containsKey(entry.getKey())) 
    .map(new Function<Entry<Object, Object>, Entry<String, String>>(){ 
     @Override 
     public Entry<String, String> apply(Entry<Object, Object> entry) { 
      return new Entry<String, String>() { 
       @Override 
       public String setValue(String value) { 
        return value.trim().toLowerCase(); 
       } 

       @Override 
       public String getValue() { 
        return ((String) entry.getValue()).trim().toLowerCase(); 
       } 

       @Override 
       public String getKey() { 
        return ((String) entry.getKey()).trim().toLowerCase(); 
       } 
      }; 
     } 
    }) 
    .collect(Collectors.toMap(Entry<String,String>::getKey, Entry<String,String>::getValue))); 

的代碼解說: 我使用java.util中的屬性的類,不幸的是,性能的entrySet返回Entry<Object, Object>,不Entry<String, String>。我想要「加入」兩個屬性對象,以小寫字母表示鍵和值。因此,地圖允許將Entry<Object, Object>轉換爲Entry<String,String>。這就是爲什麼,有一個匿名課程。

回答

5

聲納被提示來代替

prop.putAll(temp.entrySet().stream() 
    .filter(entry -> !prop.containsKey(entry.getKey())) 
    .map(new Function<Entry<Object, Object>, Entry<String, String>>(){ 
     @Override 
     public Entry<String, String> apply(Entry<Object, Object> entry) { 
      return new Entry<String, String>() { 
       @Override 
       public String setValue(String value) { 
        return value.trim().toLowerCase(); 
       } 

       @Override 
       public String getValue() { 
        return ((String) entry.getValue()).trim().toLowerCase(); 
       } 

       @Override 
       public String getKey() { 
        return ((String) entry.getKey()).trim().toLowerCase(); 
       } 
      }; 
     } 
    }) 
    .collect(Collectors.toMap(Entry::getKey, Entry::getValue))); 

(I去除收集器中的不必要的類型的參數)

prop.putAll(temp.entrySet().stream() 
    .filter(entry -> !prop.containsKey(entry.getKey())) 
    .map(entry -> new Entry<String, String>() { 
     @Override 
     public String setValue(String value) { 
      return value.trim().toLowerCase(); 
     } 

     @Override 
     public String getValue() { 
      return ((String) entry.getValue()).trim().toLowerCase(); 
     } 

     @Override 
     public String getKey() { 
      return ((String) entry.getKey()).trim().toLowerCase(); 
     } 
    }) 
    .collect(Collectors.toMap(Entry::getKey, Entry::getValue))); 

其使用λ表達式作爲替換爲匿名內部類實施Function,而不是Entry實現。

儘管如此,在這裏手動實現Entry接口沒有任何意義,尤其是在違反本合同中實際不需要的setValue方法的情況下。你只需要一個不變的Entry實例,因此,你可以創建一個現有的類的實例,而不是:

prop.putAll(temp.entrySet().stream() 
    .filter(entry -> !prop.containsKey(entry.getKey())) 
    .map(entry -> new AbstractMap.SimpleImmutableEntry<>(
     ((String) entry.getKey()).trim().toLowerCase(), 
     ((String) entry.getValue()).trim().toLowerCase())) 
    .collect(Collectors.toMap(Entry::getKey, Entry::getValue))); 

作爲最後的改進,你可以擺脫Entry實例的全部,在功能進行轉換時傳遞給toMap收藏者:

prop.putAll(temp.entrySet().stream() 
    .filter(entry -> !prop.containsKey(entry.getKey())) 
    .collect(Collectors.toMap(
     entry -> ((String) entry.getKey()) .trim().toLowerCase(), 
     entry -> ((String) entry.getValue()).trim().toLowerCase())));