2017-11-02 4 views
0

Ich habe eine Methode geschrieben, die einen Namen von einem Feld nimmt und wenn es ein essentielles Feld ist, wird der Wert für das Feld berechnet und in die Karte für den Schlüssel gelegt.Wie implementiert man computeIfAbsent, um Objektwert zurückzugeben?

private final Map<String, Object> valuesMap = new HashMap<>(); 

private void saveValues(String name) { 
     if (dataStore.isEssentialField(name)) { 
      valuesMap.put(name, calculateValue(name)); 
     } 
    } 

Jetzt möchte ich folgendes erreichen: wenn bereits ein Wert mit dem „name“ oder die Taste zugeordnet ist, ist nicht „essentialField“, die Methode muss den vorhandenen Wert zurückgeben und nichts berechnen.

Ich nehme an, dass es mit computeIfAbsent Methode einer Map-Schnittstelle erreicht werden kann, aber nicht sicher, wie man das korrekt implementiert. Wie sollte die Funktion in diesem Fall implementiert werden?

private Object saveValues(String name) { 
     if (dataStore.isEssentialField(name)) { 
      Object newValue = valuesMap.computeIfAbsent(name, -> (Function<? super String, ?>) calculateValue(name)); 
     } 
return .... ? // How can the existing value be returned here? 
    } 
+1

Es ist ein Loch in der Anforderung „, wenn bereits ein Wert Wenn der Schlüssel "Name" zugeordnet ist oder der Schlüssel nicht "essentialField" ist, muss die Methode den vorhandenen Wert zurückgeben ". Was ist, wenn der Schlüssel nicht wichtig ist und kein Wert vorhanden ist? – GPI

+0

'return datastore.get (Name);' – Lino

+0

@GPI wahrscheinlich die einzige Option in der Situation, wenn der Schlüssel nicht wichtig ist und es keinen vorhandenen Wert gibt, ist die Rückgabe von 'null'. – samba

Antwort

3

Sie können eine Lambda-Funktion wie folgt verwenden:

private Object saveValues(String name) { 
    if (dataStore.isEssentialField(name)) { 
     return valuesMap.computeIfAbsent(name, this::calculateValue); 
    } 
    return valuesMap.get(name); 
} 

Der eher klassische Ansatz wäre:

private Object saveValues(String name) { 
    Object storedValue = valuesMap.get(name); 
    if (dataStore.isEssentialField(name)) { 
     if (storedValue != null) { 
      return storedValue; 
     } 
     storedValue = calculateValue(name); 
     valuesMap.put(name, storedValue); 
    } 
    return storedValue; 
} 
+0

können Sie sagen, was 's' in Ihrer vorherigen Bearbeitung bedeutet' return valuesMap.ComputeIfAbsent (Name, s -> calculateValue (Name)); '? – samba

+0

Das hätte 'return valuesMap.computeIfAbsent (Name, s -> calculateValue (s));'. Lambda sind nur eine kurze Art, Code aufzurufen. In diesem Szenario versteht der Compiler, dass es sich um eine "Schnittstelle" handelt, die nur eine einzige zu implementierende Methode hat ("apply (...);" genannt). 's -> calculateValue (s)' erstellt eine 'neue Funktion ' und implementiert die einzige Methode, die es gibt mit 'calculateValue (s)' wobei 's' der einzige Parameter in' apply (T t) ist; '. –

+1

'this :: calculateValue' fährt nur einen Schritt weiter und teilt den Parameter, da der Compiler weiß, dass ein Parameter in unsere Implementierung und ein Parameter, der an 'calculateValue (...)' übergeben wird, enthalten sind. In diesem Fall können Sie es wie oben beschrieben schreiben (obwohl Sie wissen sollten, dass die Java-Laufzeitumgebung ein Objekt im Hintergrund erstellt, das Speicherplatz verbraucht und Zeit für die Zuweisung und das Sammeln von Daten wie jedes andere Objekt kostet) –

Verwandte Themen