La question demandait comment transformer un tableau en liste. La plupart des réponses à ce jour ont montré comment créer une nouvelle liste avec le même contenu que le tableau, ou faisant référence à des bibliothèques tierces. Cependant, il existe des options simples et intégrées pour ce type de conversion. Certains d'entre eux ont déjà été esquissés dans d'autres réponses (par exemple celle-ci ). Mais j'aimerais souligner et élaborer certains degrés de liberté pour la mise en œuvre ici, et montrer les avantages potentiels, les inconvénients et les mises en garde.
Il y a au moins deux distinctions importantes à faire:
- Si la liste résultante doit être une vue sur le tableau ou si elle doit être une nouvelle liste
- Si la liste résultante doit être modifiable ou non
Les options seront résumées ici rapidement, et un exemple de programme complet est affiché au bas de cette réponse.
Créer une nouvelle liste ou créer une vue sur la baie
Lorsque le résultat doit être une nouvelle liste, l'une des approches des autres réponses peut être utilisée:
List<Long> list = Arrays.stream(array).boxed().collect(Collectors.toList());
Mais il faut tenir compte des inconvénients de cette opération: un tableau avec 1000000 long
valeurs occupera environ 8 mégaoctets de mémoire. La nouvelle liste occupera également environ 8 mégaoctets. Et bien sûr, le tableau complet doit être parcouru lors de la création de cette liste. Dans de nombreux cas, la création d'une nouvelle liste n'est tout simplement pas nécessaire. Au lieu de cela, il suffit de créer une vue sur le tableau:
// 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);
(Voir l'exemple en bas pour une implémentation de la toList
méthode)
L'implication d'avoir une vue sur le tableau est que les changements dans le tableau seront visibles dans la liste:
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!
Heureusement, créer une copie (c'est-à-dire une nouvelle liste qui n'est pas affectée par les modifications du tableau) à partir de la vue est trivial:
List<Long> copy = new ArrayList<Long>(asList(array));
Maintenant, il s'agit d'une copie fidèle, équivalente à ce qui est réalisé avec la solution basée sur le flux présentée ci-dessus.
Créer une vue modifiable ou une vue non modifiable
Dans de nombreux cas, cela suffira lorsque la liste est en lecture seule . Le contenu de la liste résultante ne sera souvent pas modifié, mais uniquement transmis au traitement en aval qui ne lit que la liste.
Permettre des modifications de la liste soulève quelques questions:
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?
Il est possible de créer une vue de liste sur le tableau qui est modifiable . Cela signifie que les changements dans la liste, comme la définition d'une nouvelle valeur à un certain index, seront visibles dans le tableau.
Mais il n'est pas possible de créer une vue de liste structurellement modifiable . Cela signifie qu'il n'est pas possible d'effectuer des opérations qui affectent la taille de la liste. C'est simplement parce que la taille du tableau sous-jacent ne peut pas être modifiée.
Ce qui suit est un MCVE montrant les différentes options d'implémentation et les manières possibles d'utiliser les listes résultantes:
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();
}
}
La sortie de l'exemple est affichée ici:
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