Cómo usar subList ()

79

Tengo una página JSF que muestra una lista de archivos de registro de Glassfish. Utilizo la carga diferida para la paginación. Guardo la lista de los nombres de los archivos de registro en Java List.

private List<directoryListObj> dataList = new ArrayList<>();

dataList = dataList.subList(firstRow, lastRow);

Y aquí esta el problema. Por ejemplo, tengo 35 archivos en el directorio. Cuando hago esto

dataList = dataList.subList(5, 15);

Funciona bien. Pero cuando hago esto:

dataList = dataList.subList(30, 38);

Recibo un índice incorrecto de error porque quiero obtener un índice fuera de la Lista. ¿Cómo puedo, por ejemplo, devolver elementos de la lista de 30 a 35? Quiero si quiero obtener un índice de 30 a 40, pero si solo hay 35 índices para obtener solo 5.

usuario1285928
fuente
13
dataList = dataList.subList(30, 38 > dataList.size() ? dataList.size() : 38);
pb2q
18
OdataList.subList(30, Math.min(38, dataList.size())
Ismail Badawi
1
@ pb2q parece que ha perdido la oportunidad de una respuesta.
Luiggi Mendoza
Si observa APIdoc , notará que arroja IndexOutOfBoundsException - endpoint index value out of range (fromIndex < 0 || toIndex > size). Por lo tanto, consulte el APIdoc para obtener sugerencias en el futuro.
zeller

Respuestas:

97

El uso subList(30, 38);fallará porque el índice máximo 38 no está disponible en la lista, por lo que no es posible.

La única forma puede ser antes de pedir la sublista, usted determina explícitamente el índice máximo usando el método de tamaño de lista ().

por ejemplo, compruebe el tamaño, que devuelve 35, así que llame sublist(30, size());

O

COPIADO DEL comentario pb2q

dataList = dataList.subList(30, 38 > dataList.size() ? dataList.size() : 38);
kosa
fuente
6
Eso también fallaría si la lista tiene menos de 30 elementos.
Haroldo_OK
@Haroldo_OK: Sí, tienes razón, pero se supone que la lista tiene más de 30 elementos.
kosa
3
PrefierodataList = dataList.subList(30, Math.min(38, dataList.size()));
Benny Bottema
46

He implementado y probado este; debería cubrir la mayoría de las bases:

public static <T> List<T> safeSubList(List<T> list, int fromIndex, int toIndex) {
    int size = list.size();
    if (fromIndex >= size || toIndex <= 0 || fromIndex >= toIndex) {
        return Collections.emptyList();
    }

    fromIndex = Math.max(0, fromIndex);
    toIndex = Math.min(size, toIndex);

    return list.subList(fromIndex, toIndex);
}
Haroldo_OK
fuente
4
Esta debería ser la respuesta aceptada, la única que se molestó en probar su código.
Ed Randall
2
Muy útil, gracias. Romper esto en un método tiene más sentido que tratar de envolver la lógica en operadores ternarios, simplemente se vuelve demasiado difícil de leer de esa manera.
Steve
43

Para obtener el último elemento, simplemente use el tamaño de la lista como segundo parámetro. Entonces, por ejemplo, si tiene 35 archivos y desea los últimos cinco, haría:

dataList.subList(30, 35);

Una forma segura garantizada de hacer esto es:

dataList.subList(Math.max(0, first), Math.min(dataList.size(), last) );
Joe K
fuente
4
Eso también fallaría si 'primero' es mayor que el tamaño de la lista.
Haroldo_OK
3
@Haroldo_OK: ¡o si lastes negativo!
Tagir Valeev
También fallará sifirst >= last
augurar
7

Puede usar secuencias en Java 8. Para obtener siempre 10 entradas como máximo, puede hacer:

dataList.stream().skip(5).limit(10).collect(Collectors.toList());
dataList.stream().skip(30).limit(10).collect(Collectors.toList());
Stefan Haberl
fuente