Reputation: 2809
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
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
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
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
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
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