2016-07-04 17 views
0

Als einfache persönliche Übung möchte ich folgendes tun:Java - Objekt-Pool mit gleichen Referenzen

  • Erstellen Sie eine Klasse, die einen einzigen ganzzahligen Wert
  • Keine zwei Objekte dieser Klasse repräsentieren mit der gleichen ganzzahligen Wert sollte jederzeit in der Zeit existieren

Dies ist, wie ich Ansatz das Problem:

public class MyClass { 

    // Static pool 
    private static HashSet<MyClass> pool; 

    // Integer value each object holds 
    private int value; 

    static { 
    pool = new HashSet<MyClass>(); 
    } 

    // private Constructor 
    private MyClass(int value) { 
    this.value = value; 
    } 

    // Static public method to create MyClass objects 
    public MyClass create(int value) { 
     // Create tmp object with private constructor 
     MyClass tmp = new MyClass(value); 

     // At this point I want to check, whether an object with the 
     // same integer value exists in the HashSet. 
     // If this is the case I would like to return a reference to 
     // the object in the HashSet (the GC will remove tmp). 
     // Otherwise I would like to add tmp to the HashSet and return 
     // a reference to tmp. 
    } 

} 

Ein Teil der Frage wird als Teil eines Kommentars im oben angegebenen Code geschrieben. Ich bin neugierig auf folgende Dinge. Wenn ich equals(Object obj) nicht überschreibe, gibt pool.contains(tmp) immer false zurück (da der Standard equals(Object obj) geerbt von Object Tests als Referenz. Ich könnte equals(Object obj) überschreiben, um die value-Felder der Objekte zu vergleichen, aber wie würde ich die Referenz aus dem HashSet erhalten ?. zu ihm zurückkehren

muss ich mit hashcode()

+1

Gibt es Gründe, nicht eine 'Karte ' zu benutzen? – Amit

Antwort

3

Sie verwenden Java 8, verwenden Angenommen, ein Map<Integer, MyClass>:

private static Map<Integer, MyClass> map = new HashMap<>(); 

Dann in Ihrer Methode:

public MyClass create(int value) { 
    synchronized (map) { 
    return map.computeIfAbsent(value, MyClass::new); 
    } 
} 
+1

Oder 'computeIfAbsent (Wert, MyClass :: neu)'. –

+0

Könnten Sie bitte ein wenig, was diese magischen Linien tun? 'synchronized',' computeIfAbsent' + * LambdaMagic * ... – Matthias

+0

['computeIfAbsent'] (https://docs.oracle.com/javase/8/docs/api/java/util/Map.html#computeIfAbsent-K -java.util.function.Function-) wird im Javadoc der Methode beschrieben. 'synchronized' ist notwendig, weil es eine HashMap ist und [" Wenn mehrere Threads gleichzeitig auf eine Hash-Map zugreifen und mindestens einer der Threads die Map strukturell modifiziert, muss sie extern synchronisiert werden. "] (https://docs.oracle .com/javase/8/docs/api/java/util/HashMap.html). Das Lambda ist einfach eine Sache, um die neue Instanz zu erstellen, wenn sich der Schlüssel nicht in der Karte befindet. –

2

alles tun, verwenden Sie einfach einen Map<Integer, MyClass>

+0

Ich kann die Antwort in 6 Minuten akzeptieren. Ich freue mich aber auch auf die Antwort unten. – Matthias

+0

@Matthias - stellen Sie sicher, dass Sie das verstehen .. Ich wollte die Dinge nicht komplizieren, aber da es draußen ist ... – Amit