Die Frage lautete, wie ein Array in eine Liste umgewandelt werden kann. Die meisten Antworten zeigten bisher, wie eine neue Liste mit demselben Inhalt wie das Array erstellt oder auf Bibliotheken von Drittanbietern verwiesen wird. Es gibt jedoch einfache, integrierte Optionen für diese Art der Konvertierung. Einige von ihnen wurden bereits in anderen Antworten skizziert (z . B. diese ). Ich möchte hier jedoch auf bestimmte Freiheitsgrade für die Implementierung hinweisen und diese ausarbeiten und die potenziellen Vor- und Nachteile sowie Vorbehalte aufzeigen.
Es sind mindestens zwei wichtige Unterscheidungen zu treffen:
- Gibt an, ob die resultierende Liste eine Ansicht des Arrays oder eine neue Liste sein soll
- Ob die resultierende Liste geändert werden soll oder nicht
Die Optionen werden hier schnell zusammengefasst, und am Ende dieser Antwort wird ein vollständiges Beispielprogramm angezeigt.
Erstellen einer neuen Liste im Vergleich zum Erstellen einer Ansicht des Arrays
Wenn das Ergebnis eine neue Liste sein soll, kann einer der Ansätze aus den anderen Antworten verwendet werden:
List<Long> list = Arrays.stream(array).boxed().collect(Collectors.toList());
Dabei sollten jedoch die Nachteile berücksichtigt werden: Ein Array mit 1000000- long
Werten belegt ungefähr 8 Megabyte Speicher. Die neue Liste wird auch ungefähr 8 Megabyte belegen. Und natürlich muss beim Erstellen dieser Liste das gesamte Array durchlaufen werden. In vielen Fällen ist das Erstellen einer neuen Liste einfach nicht erforderlich. Stattdessen reicht es aus, eine Ansicht des Arrays zu erstellen :
// This occupies ca. 8 MB
long array[] = { /* 1 million elements */ }
// Properly implemented, this list will only occupy a few bytes,
// and the array does NOT have to be traversed, meaning that this
// operation has nearly ZERO memory- and processing overhead:
List<Long> list = asList(array);
(Eine Implementierung der toList
Methode finden Sie im Beispiel unten. )
Wenn Sie eine Ansicht des Arrays haben, bedeutet dies, dass Änderungen im Array in der Liste sichtbar sind:
long array[] = { 12, 34, 56, 78 };
List<Long> list = asList(array);
System.out.println(list.get(1)); // This will print 34
// Modify the array contents:
array[1] = 12345;
System.out.println(list.get(1)); // This will now print 12345!
Glücklicherweise ist das Erstellen einer Kopie (dh einer neuen Liste, die nicht von Änderungen im Array betroffen ist) aus der Ansicht trivial:
List<Long> copy = new ArrayList<Long>(asList(array));
Dies ist eine echte Kopie, die dem entspricht, was mit der oben gezeigten Stream-basierten Lösung erreicht wird.
Erstellen einer veränderbaren oder einer nicht veränderbaren Ansicht
In vielen Fällen ist es ausreichend, wenn die Liste schreibgeschützt ist . Der Inhalt der resultierenden Liste wird häufig nicht geändert, sondern nur an die nachgeschaltete Verarbeitung übergeben, die nur die Liste liest.
Das Zulassen von Änderungen an der Liste wirft einige Fragen auf:
long array[] = { 12, 34, 56, 78 };
List<Long> list = asList(array);
list.set(2, 34567); // Should this be possible?
System.out.println(array[2]); // Should this print 34567?
list.set(3, null); // What should happen here?
list.add(99999); // Should this be possible?
Es ist möglich, eine Listenansicht für das Array zu erstellen, die geändert werden kann . Dies bedeutet, dass Änderungen in der Liste, wie das Festlegen eines neuen Werts für einen bestimmten Index, im Array sichtbar sind.
Es ist jedoch nicht möglich, eine Listenansicht zu erstellen, die strukturell geändert werden kann . Dies bedeutet, dass keine Vorgänge ausgeführt werden können, die sich auf die Größe der Liste auswirken . Dies liegt einfach daran, dass die Größe des zugrunde liegenden Arrays nicht geändert werden kann.
Das folgende MCVE zeigt die verschiedenen Implementierungsoptionen und die möglichen Verwendungsmöglichkeiten der resultierenden Listen:
import java.util.AbstractList;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.RandomAccess;
public class PrimitiveArraysAsLists
{
public static void main(String[] args)
{
long array[] = { 12, 34, 56, 78 };
// Create VIEWS on the given array
List<Long> list = asList(array);
List<Long> unmodifiableList = asUnmodifiableList(array);
// If a NEW list is desired (and not a VIEW on the array), this
// can be created as well:
List<Long> copy = new ArrayList<Long>(asList(array));
System.out.println("array : " + Arrays.toString(array));
System.out.println("list : " + list);
System.out.println("unmodifiableList: " + unmodifiableList);
System.out.println("copy : " + copy);
// Modify a value in the array. The changes will be visible
// in the list and the unmodifiable list, but not in
// the copy.
System.out.println("Changing value at index 1 of the array...");
array[1] = 34567;
System.out.println("array : " + Arrays.toString(array));
System.out.println("list : " + list);
System.out.println("unmodifiableList: " + unmodifiableList);
System.out.println("copy : " + copy);
// Modify a value of the list. The changes will be visible
// in the array and the unmodifiable list, but not in
// the copy.
System.out.println("Changing value at index 2 of the list...");
list.set(2, 56789L);
System.out.println("array : " + Arrays.toString(array));
System.out.println("list : " + list);
System.out.println("unmodifiableList: " + unmodifiableList);
System.out.println("copy : " + copy);
// Certain operations are not supported:
try
{
// Throws an UnsupportedOperationException: This list is
// unmodifiable, because the "set" method is not implemented
unmodifiableList.set(2, 23456L);
}
catch (UnsupportedOperationException e)
{
System.out.println("Expected: " + e);
}
try
{
// Throws an UnsupportedOperationException: The size of the
// backing array cannot be changed
list.add(90L);
}
catch (UnsupportedOperationException e)
{
System.out.println("Expected: " + e);
}
try
{
// Throws a NullPointerException: The value 'null' cannot be
// converted to a primitive 'long' value for the underlying array
list.set(2, null);
}
catch (NullPointerException e)
{
System.out.println("Expected: " + e);
}
}
/**
* Returns an unmodifiable view on the given array, as a list.
* Changes in the given array will be visible in the returned
* list.
*
* @param array The array
* @return The list view
*/
private static List<Long> asUnmodifiableList(long array[])
{
Objects.requireNonNull(array);
class ResultList extends AbstractList<Long> implements RandomAccess
{
@Override
public Long get(int index)
{
return array[index];
}
@Override
public int size()
{
return array.length;
}
};
return new ResultList();
}
/**
* Returns a view on the given array, as a list. Changes in the given
* array will be visible in the returned list, and vice versa. The
* list does not allow for <i>structural modifications</i>, meaning
* that it is not possible to change the size of the list.
*
* @param array The array
* @return The list view
*/
private static List<Long> asList(long array[])
{
Objects.requireNonNull(array);
class ResultList extends AbstractList<Long> implements RandomAccess
{
@Override
public Long get(int index)
{
return array[index];
}
@Override
public Long set(int index, Long element)
{
long old = array[index];
array[index] = element;
return old;
}
@Override
public int size()
{
return array.length;
}
};
return new ResultList();
}
}
Die Ausgabe des Beispiels wird hier gezeigt:
array : [12, 34, 56, 78]
list : [12, 34, 56, 78]
unmodifiableList: [12, 34, 56, 78]
copy : [12, 34, 56, 78]
Changing value at index 1 of the array...
array : [12, 34567, 56, 78]
list : [12, 34567, 56, 78]
unmodifiableList: [12, 34567, 56, 78]
copy : [12, 34, 56, 78]
Changing value at index 2 of the list...
array : [12, 34567, 56789, 78]
list : [12, 34567, 56789, 78]
unmodifiableList: [12, 34567, 56789, 78]
copy : [12, 34, 56, 78]
Expected: java.lang.UnsupportedOperationException
Expected: java.lang.UnsupportedOperationException
Expected: java.lang.NullPointerException