2015-01-17 18 views
6

Ich habe folgendes:Wie konvertiert man Java 8 map.remove in Java 1.6?

 fruitMap.remove(fruitId, fruitProperties); 

Die fruitMap ist:

private Map<FruitId, FruitProperties> fruitMap = new HashMap<FruitId, FruitProperties>(); 

Wenn ich versuche, meinen Code ich eine bekommen zu bauen:

ERROR 
The method remove(Object) in the type Map<MyImplementation.FruitId, FruitProperties> 
is not applicable for the arguments (Map<MyImplementation.FruitId, FruitProperties>) 

Was ist das Problem?

Beachten Sie, dass dieser Aufruf innerhalb einer Methode "removeFruit()" in meiner "FruitImplementation" -Klasse ist.

+0

Wie ist 'fruitId' definiert? – Todd

Antwort

2

Die remove(key, value) Methode entfernt den Eintrag für key, wenn es derzeit auf value zugeordnet ist. Die Methode wurde in Java 1.8 hinzugefügt. Die Javadoc für die Map Schnittstelle erwähnt die folgende Standardimplementierung:

if (map.containsKey(key) && Objects.equals(map.get(key), value)) { 
    map.put(key, newValue); 
    return true; 
} else 
    return false; 

Da die Objects Klasse nur in Java 1.7, Java hinzugefügt wurden 1,6 Sie die Gleichheit schreiben selbst testen. Also, wenn Sie den Rückgabewert des Verfahrens nicht benötigen, können Sie ersetzen map.remove(key, value) mit:

if (map.containsKey(key) { 
    Object storedValue = map.get(key); 
    if (storedValue == null ? value == null : storedValue.equals(value)) { 
     map.remove(key); 
    } 
} 

Beachten Sie, dass dies nicht Thread-sicher. Wenn Sie aus mehreren Threads auf die Map zugreifen, müssen Sie einen synchronisierten Block hinzufügen.

2

Sie werden sich um den Wert zu testen:

if(fruitProperties.equals(fruitMap.get(fruitId)) { 
    fruitMap.remove(fruitId); 
} 

Hinweis, hier meine Implementierung vorausgesetzt, dass Sie ein nicht-null fruitProperties Objekt testen.

7

Von the Javadocs:

Die Standardimplementierung entspricht, für diese Karte:

if (map.containsKey(key) && Objects.equals(map.get(key), value)) { 
    map.remove(key); 
    return true; 
} else 
    return false; 

Die Standardimplementierung übernimmt keine Garantie über Synchronisation oder Unteilbarkeit Eigenschaften dieses Verfahrens. Jede Implementierung, die Atomizitätsgarantien bereitstellt, muss diese Methode überschreiben und ihre Parallelitätseigenschaften dokumentieren.

Sie könnten also diese Standardimplementierung verwenden. Leg es vielleicht in eine statische Hilfsmethode.

Wenn dies jedoch threadsicher sein soll, müssen Sie möglicherweise einen Synchronisierungscode hinzufügen (oder in Erwägung ziehen, eine ConcurrentMap zu verwenden, die übrigens bereits seit Java 5 die Remove-Methode verwendet).

+2

Java 6 hat nicht die Klasse "Objects". –

+3

ah .. Ich werde das als Übung für den Leser verlassen. :-) – Thilo

+0

Ich denke, es muss synchronisiert werden? Wie kommt man dazu, keine Objects-Klasse zu haben? Ich bin mir nicht sicher, ob es sein muss oder nicht, ich möchte diesen Code beibehalten, ohne etwas zu kaputt zu machen. – Rolando

1

Sie müssen die folgenden vorausgesetzt, Ihre Werte nicht null

if (fruitProperties.equals(fruitMap.get(fruitId)) 
    fruitMap.remove(fruitId); 

Hinweis sein kann: für diesen Thread-sicher sein zu können, muss dies in einem synchronized Block wickeln.

1

Hier ist die vollständige Lösung, Handhabung synchronization und spezifische Fälle wie null Werte.

synchronized (fruitMap) 
{ 
    if ((fruitMap.containsKey(fruitId) // The key is present 
    && (
      (fruitProperties == null && fruitMap.get(fruitId) == null) // fruitProperties is null, so is the stored value 
     || (fruitProperties != null && fruitProperties.equals(fruitMap.get(fruitId))) 
     ) 
    ) 
    { 
     fruitMap.remove(fruitId); 
    } 
} 

Es ist in Java arbeitet 6, dann ist es ein Äquivalent zu:

fruitMap.remove(fruitId, fruitProperties); 
1

Objects.equals eine Implementierung wie diese hat:

public static boolean equals(Object a, Object b) { 
    return (a == b) || (a != null && a.equals(b)); 
} 

daher die Standardimplementierung von remove:

if (map.containsKey(key) && Objects.equals(map.get(key), value)) { 
    map.remove(key); 
    return true; 
} else 
    return false; 

Kann in Java 6 geschrieben werden als:

if (map.containsKey(key) && ((map.get(key) == value) || (map.get(key) != null && map.get(key).equals(value)))) { 
    map.remove(key); 
    return true; 
} else 
    return false; 
1

Gemäß der Java Doc, entfernen (Objektschlüssel, Objektwert)

Löscht den Eintrag für den angegebenen Schlüssel nur, wenn sie zur Zeit abgebildet werden auf den angegebenen Wert.

Wenn equals() richtig definiert sind, können Sie so etwas wie dieses

FruitProperties valueFromMap = map.get(key); 
if(valueFromMap != null){ 
    if(valueFromMap == originalValue || valueFromMap.equals(originalValue)){ 
    map.remove(key); 
    } 
} 

Jetzt tun, dass Sie einfach HashMap verwenden, gehe ich davon aus, dass Sie kümmern sich um Thread-Sicherheit nehmen werde durch entweder synchronisieren oder ändern Sie es zu ConcurrentHashMap :)

Verwandte Themen