2017-12-28 65 views
0

私は、埋め込みオブジェクトタイプのプロパティを持つクラスとディレクトリのプロパティを持つファイルを含む別々のディレクトリを持っています。 クラスの最初のプロパティがロードされ、次にloadEmbeddedTypeProps()メソッドがクラスのフィールドを通過し、特定のタイプのフィールド(下の例では列挙型を使用)が見つかった場合は、そのプロパティのタイプも別のディレクトリからロードされます。最後に、クラスとその埋め込み型のプロパティがマージされますmergeProperties()メソッドが呼び出されます。computeIfAbsent()を使ってHashMapのデータをキャッシュする方法は?

埋め込み型のプロパティを静的なcachedProperties HashMapにキャッシュすることに決めました。 すでに特定のキーのプロパティが含まれている場合は、cachedPropertiesから取得し、locaProperties HashMapとマージします。そうでない場合は、ファイルからプロパティをダウンロードしています(loadPropsForType()が呼び出されます)。

ロジックは期待通りに機能しますが、loadEmbeddedTypeProps()メソッドのコードはcomputeIfAbsentメソッドを使用して改善される可能性があります。私は最近ラムダを実験し始めましたが、ここでどのように実装できるかはわかりません。また、それはcomputeIfAbsentを使用するのに適した場所ですか?

private static Map<String, Map<String, Properties>> cachedProperties = new HashMap<>(); 

      private Map<String, Properties> loadEmbeddedTypeProps(Class myClass) { 
       Map<String, Properties> localProperties = new HashMap<>(); 
       Arrays.stream(myClass.getFields()) 
         .filter(field -> field.getType().isAssignableFrom(Enumerated.class)) 
         .forEach(field -> { 
          String fieldName = field.getType().getSimpleName(); 
          String enumTypeName = StringUtils.uncapitalize(fieldName); 
          try { 
           if (cachedProperties.containsKey(enumTypeName)) { 
           // properties for enumerated type are already in cache 
            Map<String, Properties> propertiesFromCache = cachedProperties.get(enumTypeName); 
            mergeProperties(propertiesFromCache, localProperties); 
           } else { 
           // properties for enumerated type are not cached yet 
            Map<String, Properties> loadEnumProperties = loadPropsForType(enumTypeName); 
            cachedProperties.put(enumTypeName, loadEnumProperties); 
            mergeProperties(loadEnumProperties, localProperties); 
           } 
          } catch (IOException e) { 
           e.printStackTrace(); 
          } 
         }); 
       return localProperties; 
      } 
+0

'loadPropsForType'は' IOException'を投げますか? –

+0

@ JornVerneeはい、このメソッドは 'IOException'をスローします – samba

答えて

1

あなたはcomputeIfAbsentを使用することができますが、あなたはあなたがcomputeIfAbsentに渡すラムダの内側try catchを置く必要があるだろうFunction<...>からチェック例外を投げることができないので。 nullを返す

マッピングが行われないことをcomputeIfAbsentを伝えます。

マッピング関数がnullを返す場合、マッピングは記録されません。

例外がスローされた場合、そのフィールドは基本的に無視されます。返されたenumPropertiesnullになるので、それをmergePropertiesで処理しなければならないことにご注意ください。

1

はい、ここではcomputeIfAbsent()が適切です。

Map<String, Properties> properties = 
     cachedProperties.computeIfAbsent(enumTypeName, this::loadPropsForType); 
mergeProperties(properties, localProperties); 

loadPropsForTypeと仮定すると囲むクラスのインスタンスメソッドで次のようにあなたはそれを使用することができます。それが何であれ、メソッド参照を適切に置き換えます。ここでのメソッド参照のタイプはFunction<? super String, ? extends Map<String, Properties>>のサブタイプで、computeIfAbsentのドキュメントに従っています。

関連する問題