Flavio Troia
Flavio Troia

Reputation: 2809

Custom pagination by array list

I want to create, in Java code, a custom pagination by an array list:

import org.springframework.data.domain.Sort;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Sort.Direction;
...    

    int page = 0;
    int count = 8;
    String sortOrder = "desc";
    String sortBy = "id";
    
    Sort sort = new Sort(Direction.fromString(sortOrder), sortBy);
    PageRequest pageable = new PageRequest(page, count, sort);
    
    List<Impianto> impiantos = myService.findMyMethod(); // returned 30 objects 
    Page<Impianto> pageImpianto = new PageImpl<Impianto>(impiantos, pageable, impiantos.size()); 

The script above doesn't return a page of 8 elements. Why?

N.B. the list didn't return from db.

Upvotes: 6

Views: 17645

Answers (5)

Majid Pourbarzegar
Majid Pourbarzegar

Reputation: 1

I solved with this max and min (min of list size and (pageSize * pageNo))

public Page < Model > toPageModels(List < Model > list, int pageSize, int pageNo) {
    List < Model > sorted = list.stream().sorted(Comparator.comparing(Model::getString).reversed()).toList(); // sort list with Comparator
    PageRequest pageable = PageRequest.of(pageNo, pageSize);

    int max = Math.min(pageSize * (pageNo + 1), list.size());
    int min = Math.min(pageSize * pageNo, list.size());

    getLogger().info("paginate Models by pageSize: ({}), pageNo: ({}) ,list size: ({}), min: ({}), max: ({}) ", pageSize, pageNo, list.size(),
        min, max);
    return new PageImpl < Model > (sorted.subList(min, max), pageable, list.size());
}

Upvotes: -1

Himanshi
Himanshi

Reputation: 112

for me it worked

Page<OrderLineDTO> toPage(List<OrderLineDTO> list, int pagesize, int pageNo) {

    int totalpages = list.size() / pagesize;
        PageRequest pageable = new PageRequest(pageNo, pagesize);

        int max = pageNo>=totalpages? list.size():pagesize*(pageNo+1);
        int min = pageNo >totalpages? max:pagesize*pageNo;

        logger.info("totalpages{} pagesize {} pageNo {}   list size {} min {}   max {} ...........", totalpages,pagesize, pageNo, list.size(),
                min, max);
        Page<OrderLineDTO> pageResponse = new PageImpl<OrderLineDTO>(list.subList(min, max), pageable,
                list.size());
        return pageResponse;
    }

Upvotes: 1

keith5140
keith5140

Reputation: 1394

Flavio Troia'answer is wrong, when impiantos is less than count and page is more than 1,there will an exception when call subList function, fromIndex(10) > toIndex(5) ,I made my own code like this,it is maybe redundancy,but to me it is simple to understand and right~

 List<UcShopCourseBizPojo> shopCourseBizPojos = addCourseCoupons(mcCouponLists, shopCourseLists);


        if (pageable.getOffset() > shopCourseBizPojos.size()) {
            long total = 0L;
            PageImpl<UcShopCourseBizPojo> emptyPage = new PageImpl<>(Lists.newArrayList(), pageable, total);
            resultDo.setResult(emptyPage);
            return resultDo;
        }

        if (pageable.getOffset() <= shopCourseBizPojos.size() && pageable.getOffset() + pageable.getPageSize() > shopCourseBizPojos.size()) {
            List<UcShopCourseBizPojo> bizPojos = shopCourseBizPojos.subList(pageable.getOffset(), shopCourseBizPojos.size());
            PageImpl<UcShopCourseBizPojo> pPage = new PageImpl<>(bizPojos, pageable, shopCourseLists.size());
            resultDo.setResult(pPage);
            return resultDo;
        }

        List<UcShopCourseBizPojo> ucShopCourseBizPojos = shopCourseBizPojos.subList(pageable.getOffset(), pageable.getOffset() + pageable.getPageSize());

        PageImpl<UcShopCourseBizPojo> pPage = new PageImpl<>(ucShopCourseBizPojos, pageable, shopCourseLists.size());
        resultDo.setResult(pPage);
        return resultDo;

Upvotes: 0

Roberto Parra
Roberto Parra

Reputation: 41

I made my own code based on your, to fulfill customers requirements, with no sort etc. Thank You

This is how the Controller looks like

    @RequestMapping(value="/zonas", method = RequestMethod.GET)
public String zonas(ModelMap modelMap, @PageableDefault(size=3) Pageable pageable, ZonasFilter zonasFilter, Locale locale) {
    LOGGER.info("Cargando la vista del índice de Zonas.");
    List<Zona> zonas;
    try {
        zonas = zonasService.loadAll();
        int max = (pageable.getPageSize()*(pageable.getPageNumber()+1)>zonas.size())? zonas.size(): pageable.getPageSize()*(pageable.getPageNumber()+1);
        modelMap.addAttribute("zonas",new PageImpl<Zona>(zonas.subList(pageable.getPageSize()*pageable.getPageNumber(), max), pageable, zonas.size()));
    } catch (ApiException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
        List<ApiError> errors=e.getErrors(); 
        for (ApiError apiError : errors) {
            modelMap.addAttribute("error", messages.getMessage(apiError.getMessage(), null, locale));
        }

    }   
    LOGGER.info("Vista del índice de  Zonascargada.");
    return "zonas/index";
}

Upvotes: 1

Flavio Troia
Flavio Troia

Reputation: 2809

I SOLVED with this workaround.

    import org.springframework.data.domain.Sort;
    import org.springframework.data.domain.PageRequest;
    import org.springframework.data.domain.Page;
    import org.springframework.data.domain.PageImpl;
    import org.springframework.data.domain.Sort.Direction;
    ...    

        int page = 0;
        int count = 8;
        String sortOrder = "desc";
        String sortBy = "id";

        Sort sort = new Sort(Direction.fromString(sortOrder), sortBy);
        PageRequest pageable = new PageRequest(page, count, sort);

        List<Impianto> impiantos = myService.findMyMethod(); // returned 30 objects 
        int max = (count*(page+1)>impiantos.size())? impiantos.size(): count*(page+1);

        Page<Impianto> pageImpianto = new PageImpl<Impianto>(impiantos.subList(page*count, max), pageable, impiantos.size());  

and I implemented a new custom comparator class

import java.lang.reflect.Field;
import java.util.Comparator;
import java.util.Date;

public class MyListComparator implements Comparator<Object> {

    final String sortBy;
    final String sortOrder;

    public MyListComparator(String sortBy, String sortOrder) {
        this.sortBy = sortBy;
        this.sortOrder = sortOrder;
    }

    @Override
    public int compare(Object o1, Object o2) {

        try {
            Field field1 = o1.getClass().getDeclaredField(sortBy);
            Field field2 = o2.getClass().getDeclaredField(sortBy);

            field1.setAccessible(true); // because the fields in Impianto entity has "private" 
            field2.setAccessible(true);

            if(o1.getClass().getDeclaredField(sortBy).getType() == Long.class){
                Long d1 = (Long) field1.get(o1);
                Long d2 = (Long) field2.get(o2);
                return (sortOrder.toLowerCase().equals("asc"))? d1.compareTo(d2) : d2.compareTo(d1);

            }else if(o1.getClass().getDeclaredField(sortBy).getType() == Date.class){
                Date d1 = (Date) field1.get(o1);
                Date d2 = (Date) field2.get(o2);
                return (sortOrder.toLowerCase().equals("asc"))? d1.compareTo(d2) : d2.compareTo(d1);

            }else{
                String d1 = (String) field1.get(o1);
                String d2 = (String) field2.get(o2);
                return (sortOrder.toLowerCase().equals("asc"))? d1.compareTo(d2) : d2.compareTo(d1);

            }
        } catch (SecurityException e) {
            throw new RuntimeException(e);
        } catch (NoSuchFieldException e) {
            throw new RuntimeException("Missing variable sortBy");
        }catch (ClassCastException e) {
            throw new RuntimeException("sortBy is not found in class list");
        } catch (IllegalArgumentException e) {
            //shoud not happen
            throw new RuntimeException(e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }
    }


}

Upvotes: 5

Related Questions