2016-07-19 24 views
-2

Ich habe eine ziemlich dumme Frage, aber ich frage mich, ob es möglich ist, Eingänge einer Hash-Karte mit equals() zu vergleichen, bevor der Compiler es für uns tun würde. Ich versuche zu ermitteln, wie oft ich ein doppeltes Schlüssel/Wert-Paar in die Karte eingegeben habe.Vergleichen von Hastable mit Gleichgestellten

Ich habe einen Code geschrieben, aber ich weiß nicht, wie man die equals() implementieren. Irgendeine Idee?

Map<String, String> newMap = new LinkedHashMap<>(); 
    newMap.put("aaa", "bbb"); 
    newMap.put("ccc", "ddd"); 
    newMap.put("eee", "fff"); 
    newMap.put("aaa", "bbb"); 
    System.out.println(newMap.size()); 

    for(String item : newMap.keySet()){ 
     System.out.println(item + " "+newMap.get(item)); 

    } 
+2

Was genau versuchen Sie zu tun? Deine Frage ist ein wenig unklar. –

+0

Nun, ich versuche tatsächlich einen Zähler zu bekommen, wie oft ich das gleiche Schlüssel-Wert-Paar eingegeben habe. –

+1

Soll die Struktur das für Sie tun? (Es ist nicht - Sie müssten Ihre eigenen schreiben.) Eine 'Map' speichert definitionsgemäß nur einen Wert pro Schlüssel, also wenn Sie einen Wert mit dem Schlüssel' "aaa" 'hinzufügen und dann einen zweiten Wert mit hinzufügen der gleiche Schlüssel, der erste ist _ersetzt_. Sie können (in Ihrem eigenen Code) 'newMap.containsKey()' verwenden, um zu sehen, ob der Schlüssel bereits in der 'Map' existiert. –

Antwort

-1
public final class PutCountingLinkedHashMap<K, V> extends LinkedHashMap<K, V> { 
    private final Map<K, Integer> putCounts = new HashMap<>(); 

    @Override 
    public V put(final K key, final V value) { 
     final int count = count(key); 
     putCounts.put(key, count + 1); 
     return super.put(key, value); 
    } 

    public int count(final K key) { 
     return putCounts.getOrDefault(key, 0); 
    } 

    public int totalDuplicatePuts() { 
     int total = 0; 
     for (int i : putCounts.values()) { 
      if (i > 1) total += i - 1; 
     } 
     return total; 
    } 
} 

Verbrauch:

PutCountingLinkedHashMap<String,String> map = new PutCountingLinkedHashMap<>(); 
map.put("aaa", "bbb"); 
map.put("ccc", "ddd"); 
map.put("eee", "fff"); 
map.put("aaa", "bbb"); 

int aaaCount = map.count("aaa"); //2 

Weitere Arbeiten sind erforderlich, um zu entscheiden, was ist, wenn etwas mit den Zählungen auf einem remove zu tun, oder clear usw.

Ich versuche, um die Anzahl der Male zu erhalten, die ich ein doppeltes Schlüssel-Wert-Paar in die Karte eingegeben habe

map.totalDuplicatePuts(); 
+0

Sie waren schneller, jetzt habe ich eine sehr ähnliche Antwort :-) – vsnyc

+0

@vsnyc aber warum hat Ihr eine private LinkedHashMap Karte; 'Feld? Entweder unterstützt es die Schnittstelle 'Map' und stellt ein Backing-Feld zur Verfügung, oder es erbt von' LinkedHashMap', aber nicht von beiden. – weston

+0

Ich werde es beheben, ich habe zuerst einen Wrapper erstellt und dann 'LinkedHashMap ' erweitert und die beiden gemischt. – vsnyc

0

Sie können dies nicht mit einer einzigen Karte, aber Sie können mit einer Abstraktion von etwas damit anfangen.

Hier ist ein Beispiel, das mit Java 8 kompatibel ist; Mit zwei Karten können wir die Tabs vollständig anzeigen, wenn ein bestimmter Schlüssel in die Karte eingegeben und basierend auf dem Schlüssel inkrementiert wird. Angenommen, dies ist in einer separaten Klasse definiert.

Map<K, V> newMap = new LinkedHashMap<>(); 
Map<K, Integer> newMapOccurrences = new HashMap<>(); 

public void put(K key, V value) { 
    newMap.put(key, value); 
    newMapOccurrences.put(key, newMapOccurrences.getOrDefault(key, 0) + 1); 
} 

public Integer getCount(K key) { 
    return newMapOccurrences.getOrDefault(key, 0); 
} 

Wenn Sie Schlüssel-Wert-Paare sicher sein zu verfolgen, das ist ein bisschen schwieriger, da es nicht wirklich eine Karte als Schlüssel-Eintrag verwendet empfohlen wird. Da Karten sowieso vom Schlüssel abgehört werden, wäre es nicht die beste Idee, beide im Auge zu behalten, und Sie könnten mit einer Auszählung rechnen. Allerdings biete ich eine Idee in Form einer , die Mai bekommen Sie in dieser Hinsicht in die richtige Richtung begonnen haben; Aber ich überlasse das als Übung für den Leser.

0

Eine Möglichkeit, dies zu tun, ist es, eine Karte zu halten, die wie oft Spuren, die Sie map.put() für einen bestimmten Schlüssel vom Typ genannt haben K.

Wenn Sie die Put-Operation soll dies automatisch verfolgen, Sie kann eine neue Map-Klasse haben, die erweitert. Dann wird die Put-Operation die Einfügezahl z.B.

public class KeyCountMap<K,V> extends LinkedHashMap<K,V> { 
    private HashMap<K, Integer> keyCountMap; 

    public KeyCountMap() { 
    this.keyCountMap = new HashMap<K, Integer>(); 
    } 

    @Override 
    public V put(K key, V value) { 
    keyCountMap.put(key, keyCountMap.getOrDefault(key, 0) + 1); 
    return super.put(key, value); 
    } 

    public int fetchKeyCount(K key) { 
    return keyCountMap.getOrDefault(key, 0); 
    } 
} 

Mit dieser Karte können Sie Ihre Schlüsseleinführungs Count durch den Aufruf fetchKeyCount z.B.

KeyCountMap<String, String> newMap = new KeyCountMap<>(); 
    newMap.put("aaa", "bbb"); 
    newMap.put("ccc", "ddd"); 
    newMap.put("eee", "fff"); 
    newMap.put("aaa", "bbb"); 
    System.out.println(newMap.fetchKeyCount("aaa")); 

EDIT: Revised Code pro Kommentare ein lokales LinkedHashMap Feld zu entfernen und das hinzugefügt Java 8 getOrDefault Methode.

+0

Richtige Idee, aber Java 8 macht dies viel weniger mit 'getOrDefault'. – Makoto

+0

Toller Tipp, danke! – vsnyc

+0

Unsere Lösungen sind ähnlich; Ich spielte mit der Idee, zu überprüfen, ob der Wert enthalten ist, aber wenn er nicht enthalten ist, erhält er trotzdem den Kardinalwert von 1. Daher hat Java 8 es sehr vereinfacht. – Makoto

-1

Ich empfehle, Ihre benutzerdefinierte "HashMap" -Klasse zu schreiben, sollte die vergleichbare Schnittstelle implementieren, dann überschreiben Sie die put (k, v) -Methode, wo Sie die benutzerdefinierte compareTo (o) Implementierung vor dem Aufruf der super.put (k, v). Hier ein Beispiel:

public class MyMap<K,V> extends HashMap<K,V> implements Comparable<Object>{ 

     @Override 
     public V put(K key, V value){ 

      //Use your custom compareTo method to see if the key already exist, before the HasMap class does it. 
      if(compareTo(key) != 0){ 
       super.put(key, value); 
       return value; 
      }else{ 
       //Do something else 
      } 
      return null; 
     } 

     @Override 
     public int compareTo(Object o) { 
      //Implement your desire logic to compare 
      //Test if the o object is an instance of desired class 
      for(K item : this.keySet()){ 
       if(o.equals(item)) 
        return 0; 
      } 
      return -1; 
     } 
    } 
+0

Kein Fan von 'Vergleichbares '. Warum muss es überhaupt vergleichbar sein? – Makoto