subList () 사용 방법


79

Glassfish 로그 파일 목록을 표시하는 JSF 페이지가 있습니다. 페이지 매김을 위해 지연 로딩을 사용합니다. 로그 파일 이름 목록을 Java에 보관 List합니다.

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

dataList = dataList.subList(firstRow, lastRow);

그리고 여기에 문제가 있습니다. 예를 들어 디렉토리에 35 개의 파일이 있습니다. 내가 이것을 할 때

dataList = dataList.subList(5, 15);

잘 작동합니다. 하지만 이렇게하면 :

dataList = dataList.subList(30, 38);

목록 외부에서 색인을 얻고 싶기 때문에 오류 색인이 잘못되었습니다. 예를 들어 30에서 35까지 List 요소를 반환하는 방법은 무엇입니까? 30에서 40까지의 인덱스를 얻고 싶지만 35 개의 인덱스 만 있으면 5 만 얻을 수 있습니다.


13
dataList = dataList.subList(30, 38 > dataList.size() ? dataList.size() : 38);
pb2q

18
또는dataList.subList(30, Math.min(38, dataList.size())
Ismail Badawi

1
@ pb2q는 답변을받을 기회를 놓친 것 같습니다.
Luiggi Mendoza

당신이 보면 APIdoc 당신은 발생 것을 알 수 있습니다 IndexOutOfBoundsException - endpoint index value out of range (fromIndex < 0 || toIndex > size). 따라서 향후 이러한 힌트에 대해서는 APIdoc을 참조하십시오.
zeller

답변:


97

subList(30, 38);목록에서 최대 인덱스 38을 사용할 수 없으므로 사용할 수 없으므로 사용 이 실패합니다.

유일한 방법은 하위 목록을 요청하기 전에 목록 크기 () 메서드를 사용하여 명시 적으로 최대 인덱스를 결정하는 것입니다.

예를 들어, 크기를 확인하면 35를 반환하므로 sublist(30, size());

또는

pb2q 주석에서 복사 됨

dataList = dataList.subList(30, 38 > dataList.size() ? dataList.size() : 38);

6
목록에 항목이 30 개 미만인 경우에도 실패합니다.
Haroldo_OK 2015-06-23

@Haroldo_OK : 예, 맞습니다.하지만 목록에 30 개 이상의 항목이 있다고 가정했습니다.
kosa

3
내가 선호dataList = dataList.subList(30, Math.min(38, dataList.size()));
베니 Bottema에게

46

나는 이것을 구현하고 테스트했습니다. 대부분의베이스를 포함해야합니다.

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);
}

4
이것은 받아 들여진 대답이어야하며, 코드를 테스트하는 데 귀찮은 유일한 사람이어야합니다.
에드 랜달

2
매우 도움이되었습니다. 감사합니다. 이것을 메서드로 나누는 것은 삼항 연산자로 논리를 래핑하는 것보다 더 의미가 있습니다. 그렇게 읽는 것은 너무 어려워집니다.
Steve

43

마지막 요소를 얻으려면 목록의 크기를 두 번째 매개 변수로 사용하십시오. 예를 들어, 35 개의 파일이 있고 마지막 5 개 파일을 원하면 다음을 수행합니다.

dataList.subList(30, 35);

이를위한 확실한 안전한 방법은 다음과 같습니다.

dataList.subList(Math.max(0, first), Math.min(dataList.size(), last) );

4
'first'가 목록 크기보다 큰 경우에도 실패합니다.
Haroldo_OK 2015-06-23

3
@Haroldo_OK : 또는 만약 last부정적!
Tagir Valeev 2015-06-23

다음 경우에도 실패합니다first >= last
augurar

7

Java 8에서 스트림을 사용할 수 있습니다. 항상 최대 10 개의 항목을 얻으려면 다음을 수행하십시오.

dataList.stream().skip(5).limit(10).collect(Collectors.toList());
dataList.stream().skip(30).limit(10).collect(Collectors.toList());
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.