2017-08-24 1 views
1

Es scheint, dass die Reihenfolge der NetBeans Schlüssel-Wert-Paare ändern neigt, wenn sie in eine HashMap Platzierung im Vergleich zu den HashMap Objekten erstellt und durch direkte javac.exejava.exe aufrufen.NetBeans Ändern der Reihenfolge der Tasten in HashMap

Betrachten Sie die folgenden Klassendefinitionen (package und import Erklärungen weggelassen):

class Coder { 

    enum Gender { FEMALE, MALE } 
    String name; 
    Gender gender; 

    Coder(String name, Gender gender) { 
     this.name = name; 
     this.gender = gender; 
    } 

    String getName() { return name; } 
    Gender getGender() { return gender; } 
} 

class Test{ 
    public static void main(String[] args) { 
     List<Coder> list = Arrays.asList(
       new Coder("Alice", Coder.Gender.FEMALE), 
       new Coder("Chuck", Coder.Gender.MALE), 
       new Coder("Bob", Coder.Gender.MALE)); 
     Map<Coder.Gender, List<String>> classification = list.stream() 
         .collect(Collectors.groupingBy(Coder::getGender, 
           Collectors.mapping(Coder::getName, Collectors.toList()))); 
     System.out.println(classification); 

     // Getting metainfo: 
     System.out.println("Actual map's type at runtime is " + 
          classification.getClass().getSimpleName()); 
     System.out.println("OS: " + System.getProperty("os.name") + 
          ", ver." + System.getProperty("os.version")); 
     System.out.println("Java ver.: " + System.getProperty("java.version")); 

     // Serializing: 
     String filename = "classification_cmd.ser"; 
     // String filename = "classification_NetBeans.ser"; // toggle commenting-out as needed 
     File file = new File(filename); 
     try (
      FileOutputStream fos = new FileOutputStream(file); 
      ObjectOutputStream outs = new ObjectOutputStream(fos) 
     ) 
     { outs.writeObject(classification); 
     } catch (IOException ioe) { ioe.printStackTrace(); }; 
    } 
} 

Kompilieren und den obigen Code direkt von der Kommandozeile in Windows (Java ver.1.8.0_066) ausgeführt wird produziert diese:

{MALE=[Chuck, Bob], {FEMALE=[Alice]} 

Unter Linux von der CLI auf meinem Raspberry Pi (Java ver.1.80_065) und über ideone.com (Java ver.1.8.0_112) Ergebnisse waren im Wesentlichen die gleichen: erste MALE-Gruppe, dann WEIBLICHE eins. Doch in NetBeans 8.1 unter Windows (Java ver.1.8.0_066) wurde der Ausgang umgekehrt:

{FEMALE=[Alice], MALE=[Chuck, Bob]} 

In allen Fällen ist die tatsächliche Art der Karte in Frage HashMap war. Serialisierung von der Karte auf der Festplatte und innen bestätigt späht, dass die Objekte in Bezug auf die Reihenfolge der Schlüssel-Wert Paare in der Tat unterschiedlich waren:

- von der Kommandozeile: enter image description here

- von innen NetBeans : meine Fragen enter image description here

Daraus folgt:

  • Warum passiert das es und
  • Was getan werden soll (ich meine, abgesehen von Zwang Sortierung wie ein TreeMap um ein benutzerdefinierten Comparator usw. gebaut Einsatz), dass die Ergebnisse genau das gleiche sein, um sicherzustellen, unabhängig davon, wie wir kompilieren und führen Sie unsere Programme aus, von der Befehlszeile oder von NetBeans?
+1

Ich verstehe, dass Sie immer noch wissen wollen, warum es passiert, aber das ist wichtig: "Diese Klasse gibt keine Garantien hinsichtlich der Reihenfolge der Karte, insbesondere garantiert sie nicht, dass die Reihenfolge im Laufe der Zeit konstant bleibt . " - [HashMap Doc] (https://docs.oracle.com/javase/7/docs/api/java/util/HashMap.html) – mumpitz

+0

Ja, ich weiß das alles und habe dieses Thema nicht aus dem Leerlauf heraus angesprochen Neugierde. Stellen Sie sich meine Überraschung vor, als ich meine OCP-Prüfung (1Z0-809) schrieb, bei der eines der Quizzes ähnlich wie meine Frage aufgebaut war und daher zwei gleichwertige, wechselseitig umgekehrte Optionen enthielt, obwohl ich nur eins ankreuzen sollte. Was die Frage noch verwirrender macht: "Es gibt keine Garantien für den Typ, die Veränderbarkeit, die Serialisierbarkeit oder die Thread-Sicherheit der zurückgegebenen Karten- oder Listenobjekte" (laut javadoc on Collectors.groupingBy()). Ich habe nur gehofft, dass da noch etwas dran ist ... –

Antwort

0

Es kann nicht garantiert werden, dass eine allgemeine Map-Implementierung die Reihenfolge der hinzugefügten Elemente beibehält.

Wenn Sie sich um diese Reihenfolge kümmern, müssen Sie eine NavigableMap wie TreeMap verwenden, die die bestellten Schlüssel hält. In der Regel müssen Sie keinen Vergleicher angeben, sondern die natürliche Reihenfolge des Schlüsseltyps, wenn keine angegeben ist.

Verwandte Themen