无数据库场景下Java SpringBoot内存HashMap存储分页实现咨询
内存HashMap存储场景下SpringBoot分页实现方案
核心实现逻辑
- 先将HashMap中的value值导出为列表,有排序需求的话先基于业务字段完成列表排序
- 校验分页参数合法性:页码默认从1开始、每页条数需大于0,非法参数直接返回默认分页配置的结果
- 计算分页边界:总条数为列表长度,起始下标 = (当前页码 - 1) * 每页条数,结束下标 = 起始下标 + 每页条数,结束下标最大不能超过总条数避免越界
- 截取对应区间的列表作为当前页返回数据
- 封装统一的分页返回结构,包含当前页码、每页条数、总条数、总页数、当前页数据集合
代码示例
1. 分页结果统一封装类
import lombok.Data; import java.util.List; @Data public class PageResult<T> { // 当前页码 private Integer pageNum; // 每页条数 private Integer pageSize; // 总条数 private Long total; // 总页数 private Integer pages; // 当前页数据 private List<T> list; public PageResult(Integer pageNum, Integer pageSize, Long total, List<T> list) { this.pageNum = pageNum; this.pageSize = pageSize; this.total = total; this.pages = (int) Math.ceil((double) total / pageSize); this.list = list; } }
2. 分页业务逻辑实现
假设业务数据存储在Map<Long, User> userMap中,User为自定义业务实体类:
import org.springframework.stereotype.Service; import java.util.ArrayList; import java.util.Comparator; import java.util.List; import java.util.Map; import java.util.stream.Collectors; @Service public class UserService { // 模拟内存存储的HashMap private final Map<Long, User> userMap = initUserData(); // 分页查询方法 public PageResult<User> pageQuery(Integer pageNum, Integer pageSize, String sortField, Boolean isAsc) { // 1. 参数兜底校验 pageNum = pageNum < 1 ? 1 : pageNum; pageSize = pageSize < 1 ? 10 : pageSize; // 2. HashMap转列表,按需排序 List<User> userList = new ArrayList<>(userMap.values()); if (sortField != null && !sortField.isEmpty()) { Comparator<User> comparator = switch (sortField) { case "id" -> Comparator.comparing(User::getId); case "createTime" -> Comparator.comparing(User::getCreateTime); // 可扩展其他排序字段 default -> Comparator.comparing(User::getId); }; userList = userList.stream() .sorted(isAsc ? comparator : comparator.reversed()) .collect(Collectors.toList()); } // 3. 计算分页边界 long total = userList.size(); int start = (pageNum - 1) * pageSize; int end = Math.min(start + pageSize, userList.size()); // 页码超过总页数时返回空列表 List<User> pageData = start >= userList.size() ? new ArrayList<>() : new ArrayList<>(userList.subList(start, end)); // 4. 封装返回结果 return new PageResult<>(pageNum, pageSize, total, pageData); } // 模拟初始化内存数据 private Map<Long, User> initUserData() { // 此处替换为实际的内存数据初始化逻辑 return Map.of(); } }
3. Controller层调用示例
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("/user") public class UserController { private final UserService userService; public UserController(UserService userService) { this.userService = userService; } @GetMapping("/page") public PageResult<User> page( @RequestParam(defaultValue = "1") Integer pageNum, @RequestParam(defaultValue = "10") Integer pageSize, @RequestParam(required = false) String sortField, @RequestParam(defaultValue = "true") Boolean isAsc ) { return userService.pageQuery(pageNum, pageSize, sortField, isAsc); } }
注意事项
List.subList()返回的是原列表的视图,直接使用会和原列表数据绑定,示例中用new ArrayList<>(subList结果)生成独立的新集合,避免后续原列表修改影响分页结果- 如果内存存储的单集合数据量超过10万级,全量转列表排序的内存开销和性能会明显下降,建议使用支持范围查询的有序内存结构(比如TreeMap)替代HashMap,减少全量遍历的性能损耗
- 可根据业务需求扩展分页结果的其他字段,比如是否为首页、是否为末页等
内容的提问来源于stack exchange,提问作者yakob
相关产品推荐
相关产品推荐

