Unterschied zwischen einer leeren ArrayList und eine ArrayList mit null Elemente?
Ich bin der Codierung einige Prüfungen für einen REST-service, die Parsen einer JSON und ich fand heraus, etwas, das klingt verrückt für mich (ich bin kein JAVA Experte überhaupt).
In Erwägung ziehen, mit zwei ArrayLists:
ArrayList<Object> list1 = new ArrayList<Object>();
ArrayList<Object> list2 = new ArrayList<Object>();
Beide Listen haben etwas gemeinsamen: Sie sind komplett leer (oder full-null-Elemente). Aber wenn ich das Tue:
list1.add(null);
Obwohl beide bleiben völlig leer, Sie haben ganz unterschiedliche Verhaltensweisen. Zu machen, und einige Methoden sind die Ergebnisse sehr unterschiedliche:
System.out.println(list1.contains(null)); //prints true!
System.out.println(list2.contains(null)); //prints false
System.out.println(CollectionUtils.isNotEmpty(list1)); //prints true
System.out.println(CollectionUtils.isNotEmpty(list2)); //prints false
System.out.println(list1.size()); //prints 1
System.out.println(list2.size()); //prints 0
Etwas Forschung zu tun, und im Blick auf die Umsetzung jedes der folgenden Methoden können Sie bestimmen, der Grund für diese Unterschiede, aber immer noch nicht verstehen, warum es gültig oder nützlich, zu unterscheiden zwischen diesen Listen.
- Warum add(item) nicht überprüfen, ob Element!=null ?
- Warum enthält(null) sagt false wenn die Liste voll ist von null?
Vielen Dank im vorraus!!!!!!
EDIT:
Bin ich meistens einverstanden mit den Antworten, aber ich bin noch nicht überzeugt alle. Dies ist die Implementierung der Methode remove:
/**
* Removes the first occurrence of the specified element from this list,
* if it is present. If the list does not contain the element, it is
* unchanged. More formally, removes the element with the lowest index
* <tt>i</tt> such that
* <tt>(o==null ? get(i)==null : o.equals(get(i)))</tt>
* (if such an element exists). Returns <tt>true</tt> if this list
* contained the specified element (or equivalently, if this list
* changed as a result of the call).
*
* @param o element to be removed from this list, if present
* @return <tt>true</tt> if this list contained the specified element
*/
public boolean remove(Object o) {
if (o == null) {
for (int index = 0; index < size; index++)
if (elementData[index] == null) {
fastRemove(index);
return true;
}
} else {
for (int index = 0; index < size; index++)
if (o.equals(elementData[index])) {
fastRemove(index);
return true;
}
}
return false;
}
/*
* Private remove method that skips bounds checking and does not
* return the value removed.
*/
private void fastRemove(int index) {
modCount++;
int numMoved = size - index - 1;
if (numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
elementData[--size] = null; //clear to let GC do its work
}
So, jetzt, wenn ich tun:
ArrayList<Object> list = new ArrayList<Object>();
list.add(null);
System.out.println(list.contains(null)); //prints true!
list.remove(null);
System.out.println(list.contains(null)); //prints false!
, was ich bin fehlt?
- Java collections erlauben von null-Elementen. Dies ist eine design-Entscheidung, du wirst damit Leben müssen (oder wählen Sie eine andere collections-framework).
- Würden Sie brauchen, um zu verstehen, was null ist: Siehe stackoverflow.com/questions/2707322/what-is-null-in-java
- Nur die code-Zeilen, die Sie gezeigt haben,
list2.size()
drucken0
, nicht2
. Ist, dass ein Fehler in den Kommentar, oder gibt es code-Zeilen, die Sie nicht zeigen? - Zu sagen
list2
ist voller Nullen ist falsch.list2
nicht enthalten nichts, nicht einmal einen einzigennull
element. - Wenn ich Ihre zweite Programm, die zweite
System.out.println
Druckefalse
. - danke für den Kommentar, ich habe bereits dieses Problem beheben!
Du musst angemeldet sein, um einen Kommentar abzugeben.
Eine Liste mit
null
ist NICHT leer. Es enthältnull
. Listen werden darf null enthalten, so können Sie setzen Sie null, wenn Sie wollen.ArrayList
.null
) in es. Schreiben Sie eine Schleife zum drucken der Elemente, und du wirst sehen, dass man führt die Schleife null mal mit no-Ausgang und man führt ein mal mit einer Zeile der Ausgabe. Einer von Ihnen wirft einenArrayIndexOutOfBounds
Ausnahme, wenn Sie versuchen, um.get(0)
und die anderen zurückkehren, um Ihnen dienull
Wert mit dem index 0.Einer
ArrayList
ausdrücklich erlaubt ist und in der Lage zu speichernnull
Werte, weil Sie vielleicht sinnvoll sein, das Programm. Und leere-Liste leer ist (d.h. nicht alles enthalten, auch nichtnull
. Nachdem Sie erfolgreich hinzufügen(null) (es gibttrue
zu signalisieren Erfolg), muss die Liste natürlich zurücktrue
auf enthält(null) als gut. In der Tat, Sie können sogar entfernen(null) aus dieser Liste und es wird wieder leer.Glücklicherweise werden Sie nicht haben, um ein java-Experte oder ein Experte in allen Bereichen.
Der beste Weg, dies zu betrachten ist wie ein Parkplatz. Ein array mit null Elementen ist wie ein Parkplatz mit nichts abgestellt in es. Ein leeres array ist, wie die Pläne für einen Parkplatz.
Einen
List
ist leer, wenn es mit null Elementen. Dies ist sowohl für die Natürliche Bedeutung des Begriffs und der test durchgeführt, indem dieisEmpty()
Methode.null
ist ein Wert, der jedemArrayList
enthalten kann als ein element. Klar, in diesem Fall die Liste hat mindestens ein element und ist daher nicht leer. Egal, was der Ausgangszustand einesList
, wenn eine Anrufungadd(null)
auf dieser Liste normalerweise abgeschlossen, dann danach die Liste nicht leer ist. Ebenso hat jedernull
element in einer Liste trägt zu seiner Größe.Fragen Joshua Bloch. Er hat es entworfen. Die meisten Menschen nehmen ihn an, sein ein ziemlich kluger Kerl, und betrachten Sie die Collections-API eine sehr erfolgreiche Anstrengungen unternommen.
Ernst, es ist eine Entwurfsentscheidung, die
List
s enthalten kannnull
Elemente. (Implementierungen zulässig sind, ablehnen, null-Werte, aberArrayList
als general-purpose-Implementierung, die Sie akzeptiert).Nicht. Nicht einfach nehmen Sie mein Wort für Sie-die Daten, die Sie präsentieren, auch widersprechen.
Die ganze Verwirrung rührt von der falschen anfängliche Vermutung, dass die ArrayLists, die Sie erstellt haben, werden in voller Nullen. Sie sind nicht, Sie sind komplett leer - das heißt, Sie haben null-Elemente. Als solche, erhalten Sie false, wenn Sie anrufen
contains(null)
auf Sie, und wahr, wenn Sie anrufenisEmpty()
.Sobald Sie Hinzugefügt haben null list1, es ist nicht mehr leer, und in der Tat enthält Sie einen null-element - liste2 ist immer noch leer und immer noch nicht null enthalten.
In deinem letzten code-Beispiel, wird der zweite Aufruf zu Sammlungen.isNotEmpty definitiv nicht true zurückgeben,. Die Liste hatte ein null-element, entfernt man es, so ist es wieder leer.
Die wichtigsten take-aways sind hier: