Ich habe einige Code, der eine Liste erstellt, initialisiert mit der Größe einer Karte:
private Set<String> mKeys = new HashSet<String>(64);
....
List<String> keyList = new ArrayList<String>(mKeys.size());
Ich erhalte eine Ausnahme: java.lang.IllegalArgumentException: Unzulässige Kapazität: -1
Kann eine Map eine Größe von -1 zurückgeben? Ich schaue mir den Quellcode für HashSet an, das von einer HashMap unterstützt wird. Der Quellcode für HashMap zeigt die Interna, wo elementCount bei einem removeEntry()-Aufruf immer dekrementiert wird. Außerdem setzen die Methoden für HashMap.empty() voraus, dass elementCount == 0 ist, was false zurückgeben würde, wenn elementCount -1 wäre.
Ist das schon mal jemandem aufgefallen? Ich kann Code um es, aber das fühlt sich wie ein Hack, die mich denken, ich bin etwas falsch mit dem aktuellen Code zu tun macht.
EDIT: Ich habe versucht, das Problem ursprünglich zu vereinfachen. Die Menge, die ich verwende, ist tatsächlich definiert als
private static Set<String> mKeys = Collections.synchronizedSet(new HashSet<String>(64));
EDIT: Der Schlüssel liegt hier möglicherweise im synchronizedSet. Aus der JavaDoc:
Es ist unbedingt erforderlich, dass der Benutzer die zurückgegebene Menge manuell synchronisiert, wenn er darüber iteriert:
Set s = Collections.synchronizedSet(new HashSet()); ... synchronized(s) { Iterator i = s.iterator(); // Must be in the synchronized block while (i.hasNext()) foo(i.next()); }
Die Nichtbeachtung dieses Hinweises kann zu nicht-deterministischem Verhalten führen.
Nicht-deterministisches Verhalten zu mir könnte eine Größe von -1 umfassen. Ich muss zurück gehen und sicherstellen, dass ich eine Synchronisierung richtig, wenn über die Menge iteriert, aber ich vermute, dass dies das Problem ist.
2 Stimmen
Es sei denn, Sie setzen etwas in
mKeys
in diesem ausgelassenen Code, machen Sie sowieso einen Fehler:mKeys.size()
gibt die Anzahl der Elemente in der DateiSet
und nicht die Anzahl der Eimer. Es geht nicht um die "Größe" der Datenstruktur, sondern um die Anzahl der enthaltenen Elemente.2 Stimmen
Ist es möglich, dass Sie die Karte beschädigen, indem Sie von mehreren Threads ohne Synchronisierung darauf zugreifen?
0 Stimmen
Der Code ist vereinfacht von dem, was ich tatsächlich tue, da es eine gewisse Synchronisation gibt. Ich werde die Frage mit genaueren Informationen aktualisieren. Ich bin fast sicher, dass dies nicht ein Problem mit Wrapping auf Integer.MAX_VALUE ist.
0 Stimmen
Außerdem ist dies nicht durchgängig reproduzierbar. Ich habe gesehen, es passiert ein paar Mal in diesem Code.