Mam stronę JSF, która wyświetla listę plików dziennika Glassfish. Używam leniwego ładowania do paginacji. Przechowuję listę nazw plików dziennika w Javie List
.
private List<directoryListObj> dataList = new ArrayList<>();
dataList = dataList.subList(firstRow, lastRow);
I tu jest problem. Na przykład mam 35 plików w katalogu. Kiedy to robię
dataList = dataList.subList(5, 15);
To działa dobrze. Ale kiedy to robię:
dataList = dataList.subList(30, 38);
Otrzymuję błąd, zły indeks, ponieważ chcę, aby indeks był poza listą. Jak mogę na przykład zwrócić elementy listy od 30 do 35? Chcę, jeśli chcę uzyskać indeks od 30 do 40, ale jeśli jest tylko 35 indeksów, aby uzyskać tylko 5.
dataList = dataList.subList(30, 38 > dataList.size() ? dataList.size() : 38);
dataList.subList(30, Math.min(38, dataList.size())
IndexOutOfBoundsException - endpoint index value out of range (fromIndex < 0 || toIndex > size)
. Więc spójrz na APIdoc, aby znaleźć takie wskazówki w przyszłości.Odpowiedzi:
Używanie
subList(30, 38);
nie powiedzie się, ponieważ max indeks 38 nie jest dostępny na liście, więc nie jest to możliwe.Jedynym sposobem może być przed zapytaniem o podlistę, jawne określenie maksymalnego indeksu przy użyciu metody list size ().
na przykład sprawdź rozmiar, który zwraca 35, więc zadzwoń
sublist(30, size());
LUB
SKOPIOWANE Z komentarza pb2q
dataList = dataList.subList(30, 38 > dataList.size() ? dataList.size() : 38);
źródło
dataList = dataList.subList(30, Math.min(38, dataList.size()));
Wdrożyłem i przetestowałem ten; powinien obejmować większość baz:
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); }
źródło
Aby uzyskać ostatni element, po prostu użyj rozmiaru listy jako drugiego parametru. Na przykład, jeśli masz 35 plików i chcesz mieć pięć ostatnich, zrobiłbyś:
dataList.subList(30, 35);
Gwarantowanym bezpiecznym sposobem na to jest:
dataList.subList(Math.max(0, first), Math.min(dataList.size(), last) );
źródło
last
jest ujemne!first >= last
Możesz użyć strumieni w Javie 8. Aby zawsze uzyskać najwyżej 10 wpisów, możesz zrobić:
dataList.stream().skip(5).limit(10).collect(Collectors.toList()); dataList.stream().skip(30).limit(10).collect(Collectors.toList());
źródło