¿Cuál es la forma más sencilla de invertir una ArrayList?
¿Cuál es la forma más sencilla de revertir este ArrayList?
ArrayList<Integer> aList = new ArrayList<>();
//Add elements to ArrayList object
aList.add("1");
aList.add("2");
aList.add("3");
aList.add("4");
aList.add("5");
while (aList.listIterator().hasPrevious())
Log.d("reverse", "" + aList.listIterator().previous());
Collections.reverse(aList);
Ejemplo ( Referencia ):
ArrayList aList = new ArrayList();
//Add elements to ArrayList object
aList.add("1");
aList.add("2");
aList.add("3");
aList.add("4");
aList.add("5");
Collections.reverse(aList);
System.out.println("After Reverse Order, ArrayList Contains : " + aList);
El truco aquí es definir "inversa". Se puede modificar la lista en su lugar, crear una copia en orden inverso o crear una vista en orden inverso.
La forma más sencilla, intuitivamente hablando , es Collections.reverse
:
Collections.reverse(myList);
Este método modifica la lista existente . Es decir, Collections.reverse
toma la lista y sobrescribe sus elementos, sin dejar ninguna copia sin revertir. Esto es adecuado para algunos casos de uso, pero no para otros; además, supone que la lista es modificable. Si esto es aceptable, estamos bien.
De lo contrario, se podría crear una copia en orden inverso :
static <T> List<T> reverse(final List<T> list) {
final List<T> result = new ArrayList<>(list);
Collections.reverse(result);
return result;
}
Este enfoque funciona, pero requiere repetir la lista dos veces. El constructor de copia ( new ArrayList<>(list)
) itera sobre la lista y también lo hace Collections.reverse
. Podemos reescribir este método para iterar solo una vez, si así lo deseamos:
static <T> List<T> reverse(final List<T> list) {
final int size = list.size();
final int last = size - 1;
// create a new list, with exactly enough initial capacity to hold the (reversed) list
final List<T> result = new ArrayList<>(size);
// iterate through the list in reverse order and append to the result
for (int i = last; i >= 0; --i) {
final T element = list.get(i);
result.add(element);
}
// result now holds a reversed copy of the original list
return result;
}
Esto es más eficiente, pero también más detallado.
Alternativamente, podemos reescribir lo anterior para usar stream
la API de Java 8, que algunas personas encuentran más concisa y legible que lo anterior:
static <T> List<T> reverse(final List<T> list) {
final int last = list.size() - 1;
return IntStream.rangeClosed(0, last) // a stream of all valid indexes into the list
.map(i -> (last - i)) // reverse order
.mapToObj(list::get) // map each index to a list element
.collect(Collectors.toList()); // wrap them up in a list
}
nótese bien. eso Collectors.toList()
ofrece muy pocas garantías sobre la lista de resultados. Si desea asegurarse de que el resultado regrese como ArrayList, use Collectors.toCollection(ArrayList::new)
en su lugar.
La tercera opción es crear una vista en orden inverso . Esta es una solución más complicada y merece una lectura adicional/su propia pregunta. El método Lists#reverse de Guava es un punto de partida viable.
La elección de la implementación "más simple" se deja como ejercicio para el lector.