2017-12-28 1 views
0

Ich habe separate Verzeichnisse mit Dateien mit Eigenschaften für Klassen und Verzeichnisse mit Eigenschaften für ihre eingebetteten Objekttypen. Erste Eigenschaften für die Klasse werden geladen, dann loadEmbeddedTypeProps() Methode durchläuft Felder einer Klasse und wenn ein Feld eines bestimmten Typs (Ich habe im Beispiel unten Aufgezählt) gefunden wird, dann werden Eigenschaften für den Typ auch aus einem anderen Verzeichnis geladen. Und schließlich werden Eigenschaften für die Klasse und für ihre eingebetteten Typen zusammengeführt mergeProperties() Methode heißt.Wie verwende ich computeIfAbsent() zum Cachen von Daten in einer HashMap?

Ich entschied mich, Eigenschaften für eingebettete Typen in einer statischen Hash-Map cachedProperties zwischenzuspeichern. Wenn es bereits Eigenschaften für einen bestimmten Schlüssel enthält, dann erhalten wir sie von cachedProperties und verschmelzen mit einer HashMap locaProperties. Wenn nicht, laden wir die Eigenschaften aus einer Datei (loadPropsForType() heißt).

Die Logik funktioniert wie erwartet aber es sieht aus wie der Code in den loadEmbeddedTypeProps() Verfahren kann durch die Verwendung computeIfAbsent Verfahren verbessert werden. Ich habe vor kurzem begonnen, mit Lambda zu experimentieren und bin mir nicht sicher, wie dies hier implementiert werden könnte. Ist es auch ein geeigneter Ort, um computeIfAbsent zu verwenden?

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

Gibt 'loadPropsForType' die' IOException'? –

+0

@JornVernee Ja, die Methode löst "IOException" aus – samba

Antwort

1

können Sie computeIfAbsent verwenden, aber da Sie nicht eine geprüfte Ausnahme von einem Function<...> würden Sie die try catch innerhalb der Lambda setzen müssen werfen können Sie auf computeIfAbsent passieren.

null Rückkehr erzählt computeIfAbsent, die keine Zuordnung vorgenommen werden sollen.

Wenn die Zuordnungsfunktion null zurückgibt, wird keine Zuordnung aufgezeichnet.

Wenn also eine Ausnahme ausgelöst wird, wird dieses Feld grundsätzlich ignoriert. Seien Sie sich jedoch bewusst, dass die zurückgegebene enumProperties auch null ist, so dass Sie damit umgehen müssen in mergeProperties.

1

Ja, computeIfAbsent() ist hier angebracht. Man könnte es wie folgt verwenden:

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

loadPropsForType Unter der Annahme ist eine Instanzmethode der umgebenden Klasse. Was auch immer es ist, ersetzen Sie die Methodenreferenz entsprechend. Der Typ der Methodenreferenz ist hier ein Untertyp von Function<? super String, ? extends Map<String, Properties>>, wie in der Dokumentation von computeIfAbsent.

Verwandte Themen