2010-03-25 10 views
5

In meiner Java-Codierung, habe ich oft mit mehreren Map<String,Map<String,foo>> oder Map<String,List<String>> und dann habe ich Probleme zu erinnern, welcher String welcher Schlüssel ist. Ich kommentiere die Deklaration mit //Map<capabiltyId,Map<groupId,foo>> oder //Map<groupId,List<capabilityId>, aber es ist nicht die beste Lösung. Wenn String nicht endgültig wäre, würde ich neue Klassen CapabilityId extends String und GroupId extends String machen, aber ich kann nicht. Gibt es einen besseren Weg zu verfolgen, welche Sache der Schlüssel ist und vielleicht der Compiler erzwingen?Bessere Art der Sicherheit in Java-Sammlungen

+0

Könnten Sie eine Enum anstelle einer Zeichenfolge verwenden? Das kann nützlich sein, wenn Sie gut definierte Schlüssel haben. – Carl

Antwort

7

Anstelle von CapabilityId erweitern String, CapabilityId könnte ein String Feld "id" bezeichnet sind; Dann könnte Ihre Map als Map<CapabilityId, Map<GroupId, Foo>> definiert werden, und Sie könnten bei den einzelnen ID-Felder durch eine getId() auf Ihre Schlüsselklassen bekommen.

Ich bin mir nicht sicher, ob ich das selbst machen würde, aber wenn ich das täte, würde ich das wahrscheinlich tun.

Sie könnten die Unordnung begrenzen, indem eine abstract GenericId Klasse mit einem ID-Feld und getId() Verfahren mit und von ihm CapabilityId und GroupId vererben haben.

+0

Das ist ein sehr Lincoln-esque Kommentar. –

+0

Ich gebe zu, dass ich für den Jerry Pournelle ging "Wenn Sie das brauchen, brauchen Sie es schlecht", aber umgekehrt. –

+0

Dies ist genau das, was ich gestern getan habe, um ein Speicherleck zu finden; Statt 150m String-Objekten konnte ich sofort erkennen, welche Map nicht gelöscht wurde, indem ich sah, wie viele nnnnKey-Objekte erstellt wurden. – rhu

9

Wrap-Strings in Wrapper-Klassen, wenn Sie wollen:

class GroupId implements Comparable { 
    private String groupId; 

    public GroupId (String groupId) { 
     this.groupId = groupId; 
    } 
    ... 
} 

Map<GroupId, List<CapabilityId>> m = ... 
+0

Warum Comparable implementieren? –

3

Eine ID Klasse, die Sie Unterklasse können, und das aus einem String Feld und Implementierungen von equals() und hashCode(), die dieses Feld verwenden.

0

zu den anderen Antworten Hinzufügen:

es Wickeln.

Es ist nicht nur eine Lösung für Ihr Problem, sondern eine gute Idee im Allgemeinen, d. H. Vermeiden Sie einfache Parameter. Ihr Code wird Lesbarkeit, Vernunft und Wartbarkeit gewinnen. Sie können alle Arten von schönen Eigenschaften hinzufügen, z. Erklären Sie es @Immutable. Wie du herausgefunden hast, ist es besser, dich daran zu erinnern und zu kontrollieren. Du besitzt die Klasse und kannst damit machen, was du willst.

2

Ich würde alles in einzelne Klasse setzen und sinnvolle Feld/Methode/Argumentnamen verwenden.

Auf diese Weise können Sie bei Methode/Argumentnamen sehen, was es erwartet/zurückgibt.

1

Es gibt eine Reihe von Möglichkeiten, auf diese zu gehen (einige bereits erwähnt):

  • Als @Roman, wickeln Sie das Mehrzweck-Typ in einen spezifischeren Typ, die stärker Typisierung gibt. Starkes Tippen gut, IMO.
  • Verwenden Sie als @nanda einen spezifischeren Sammlungstyp. Die Java-Bibliothek ist in diesem Bereich ein wenig arm. Es hängt davon ab, wie Sie sich über Abhängigkeiten fühlen.
  • Als @BalusC, bewegen Sie all die ekligen Sachen in eine eklige Klasse. Das Problem wird nicht wirklich entfernt, aber es enthält es (wie in Ghostbusters).
  • Map<String,Map<String,foo>> sieht sehr ähnlich aus wie Sie einen zusammengesetzten Schlüssel haben, d. H. Einen Schlüssel, der aus zwei Teilen besteht. Führen Sie also eine unveränderliche zusammengesetzte Schlüsselklasse ein, dh ein Wertobjekt, das die zwei Komponentenwertobjekte darstellt.
Verwandte Themen