Skip to content
Advertisement

java.lang.IllegalArgumentException: fromIndex(x) > toIndex(y)

I convert list to Page for display table of candidates with pagination, but I am getting error

java.lang.IllegalArgumentException: fromIndex(5) > toIndex(1)

How to solve this issue?

public Page<CandidatesDetailsDto> filterCandidates(Integer page, Integer pageSize) {
    page = (page == null || page < 1) ? 0 : page - 1;
    pageSize = (pageSize == null || pageSize < 1) ? 10 : pageSize;

    PageRequest pageRequest = new PageRequest(page, pageSize);

    List<CandidatesEntity> candidatesEntityList2 = candidatesService.findAll(pageRequest);
   
        int start = (int) pageRequest.getOffset();
        int end = (start + pageRequest.getPageSize()) > candidatesEntityList2.size() ? candidatesEntityList2.size() : (start + pageRequest.getPageSize());

        candidatesEntity = new PageImpl<CandidatesEntity>(candidatesEntityList2.subList(start, end), pageRequest, candidatesEntityList2.size());
    }

    return candidatesEntity.map(source -> candidatesDetailsConverter.convertTo(source));
} 

Advertisement

Answer

This exception happens because when computing start of your slice you don’t take into consideration how many objects are there in full list of candidates.

If I request from your method a page 1 of size 5, but you only have 2 candidates, look what happens:

int page = 1;
int pageOffset = 5; // page * pageSize
List<Candidate> all = Arrays.asList(customer1);

int start = 5; // = pageOffset
int end = 1;   // Math.min(start, all.size()); because min(5, 1) == 1.

Page<Candidates> page = new PageImpl(all.subList(start, end)); // this is what throws

You have to especially consider the case when someone requested from you the page that does not exist. In that case, you have to either return an empty page, or a null, or something else, but important part is it has to be processed on a different code path.

So, here’s some code that should almost work: you have to implement the nonExistentPage method yourself.

public Page<CandidatesDetailsDto> filterCandidates(Integer page, Integer pageSize) {

    page = (page == null || page < 1) ? 0 : page - 1;
    pageSize = (pageSize == null || pageSize < 1) ? 10 : pageSize;

    PageRequest pageRequest = new PageRequest(page, pageSize);

    List<CandidatesEntity> candidatesEntityList2 = candidatesService.findAll(pageRequest);

    int start = (int) pageRequest.getOffset();

    if (start <= candidatesEntityList2.size()) {
      return nonExistentPage(candidatesEntityList2.size()); // important part here
    }
    int end = Math.min(start + pageRequest.getPageSize(), candidatesEntityList2.size());

    candidatesEntity = new PageImpl<CandidatesEntity>(candidatesEntityList2.subList(start, end), pageRequest, candidatesEntityList2.size());

    return candidatesEntity.map(source -> candidatesDetailsConverter.convertTo(source));
}

/*
 * Implement this yourself: you must convey to the user that the page 
 * he requested from you does not exist.
 */
private abstract Page<CandidatesDetailsDto> nonExistentPage(int fullListSize);
User contributions licensed under: CC BY-SA
1 People found this is helpful
Advertisement