将一个List分页返回的操作方式

在 Java 后端对内存 List 数据进行分页返回给前端,有几种常见的实现方式。以下是详细的解决方案:

方案一:使用 MyBatis-Plus 的 Page 对象(推荐)

java 复制代码
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;

@RestController
@RequestMapping("/api/data")
public class DataController {
    
    /**
     * 对内存中的 List 进行分页
     */
    @GetMapping("/page")
    public Result<IPage<YourEntity>> getPageData(
            @RequestParam(defaultValue = "1") Integer current,
            @RequestParam(defaultValue = "10") Integer size) {
        
        // 1. 获取原始数据列表(这里用模拟数据)
        List<YourEntity> dataList = getDataFromMemory();
        
        // 2. 创建分页对象
        IPage<YourEntity> page = new Page<>(current, size);
        
        // 3. 设置总记录数
        page.setTotal(dataList.size());
        
        // 4. 计算分页数据
        int startIndex = (int) ((current - 1) * size);
        int endIndex = Math.min(startIndex + size, dataList.size());
        
        if (startIndex > dataList.size()) {
            page.setRecords(new ArrayList<>());
        } else {
            List<YourEntity> pageRecords = dataList.subList(startIndex, endIndex);
            page.setRecords(pageRecords);
        }
        
        return Result.success(page);
    }
    
    // 模拟从内存获取数据
    private List<YourEntity> getDataFromMemory() {
        List<YourEntity> list = new ArrayList<>();
        for (int i = 1; i <= 100; i++) {
            YourEntity entity = new YourEntity();
            entity.setId((long) i);
            entity.setName("Item " + i);
            entity.setCreateTime(new Date());
            list.add(entity);
        }
        return list;
    }
}

方案二:自定义通用分页工具类

java 复制代码
/**
 * 分页工具类
 */
@Component
public class PageUtils {
    
    /**
     * 对 List 进行分页
     */
    public static <T> IPage<T> paginateList(List<T> dataList, long current, long size) {
        IPage<T> page = new Page<>(current, size);
        page.setTotal(dataList.size());
        
        int startIndex = (int) ((current - 1) * size);
        int endIndex = Math.min(startIndex + (int) size, dataList.size());
        
        if (startIndex >= dataList.size()) {
            page.setRecords(new ArrayList<>());
        } else {
            List<T> pageList = dataList.subList(startIndex, endIndex);
            page.setRecords(new ArrayList<>(pageList)); // 避免原List修改影响
        }
        
        return page;
    }
    
    /**
     * 带排序的分页
     */
    public static <T> IPage<T> paginateList(List<T> dataList, long current, long size, 
                                          Comparator<T> comparator) {
        // 先排序再分页
        List<T> sortedList = new ArrayList<>(dataList);
        sortedList.sort(comparator);
        
        return paginateList(sortedList, current, size);
    }
}

// 控制器中使用
@RestController
@RequestMapping("/api/data")
public class DataController {
    
    @GetMapping("/page")
    public Result<IPage<YourEntity>> getPageData(
            @RequestParam(defaultValue = "1") Integer current,
            @RequestParam(defaultValue = "10") Integer size,
            @RequestParam(required = false) String sortField) {
        
        List<YourEntity> dataList = getDataFromMemory();
        
        // 可选:添加添加排序逻辑
        if ("name".equals(sortField)) {
            return Result.success(PageUtils.paginateList(dataList, current, size, 
                Comparator.comparing(YourEntity::getName)));
        }
        
        return Result.success(PageUtils.paginateList(dataList, current, size));
    }
}

方案三:封装统一响应对象

java 复制代码
/**
 * 统一的响应结果包装类
 */
@Data
public class Result<T> implements Serializable {
    private Boolean success;
    private Integer code;
    private String message;
    private T data;
    
    public static <T> Result<T> success(T data) {
        Result<T> result = new Result<>();
        result.setSuccess(true);
        result.setCode(200);
        result.setMessage("操作成功");
        result.setData(data);
        return result;
    }
}

/**
 * 自定义分页响应对象(如果不依赖 MyBatis-Plus)
 */
@Data
public class CustomPage<T> {
    private Long current;      // 当前页
    private Long size;         // 每页大小
    private Long total;        // 总记录数
    private Long pages;        // 总页数
    private List<T> records;   // 数据列表
    
    public CustomPage(Long current, Long size, Long total, List<T> records) {
        this.current = current;
        this.size = size;
        this.total = total;
        this.pages = (total + size - 1) / size; // 计算总页数
        this.records = records;
    }
    
    /**
     * 从 List 创建分页对象
     */
    public static <T> CustomPage<T> of(List<T> dataList, long current, long size) {
        long total = dataList.size();
        long startIndex = (current - 1) * size;
        long endIndex = Math.min(startIndex + size, total);
        
        List<T> pageRecords;
        if (startIndex >= total) {
            pageRecords = new ArrayList<>();
        } else {
            pageRecords = new ArrayList<>(
                dataList.subList((int) startIndex, (int) endIndex)
            );
        }
        
        return new CustomPage<>(current, size, total, pageRecords);
    }
}

方案四:结合 Stream API 的高级用法

java 复制代码
@Service
public class DataService {
    
    /**
     * 使用 Stream API 进行复杂分页
     */
    public IPage<YourEntity> getComplexPageData(long current, long size, 
                                              Map<String, Object> filters) {
        List<YourEntity> allData = getDataFromMemory();
        
        // 流式处理:过滤 -> 排序 -> 分页
        List<YourEntity> filteredData = allData.stream()
            .filter(item -> filterCondition(item, filters)) // 自定义过滤条件
            .sorted(Comparator.comparing(YourEntity::getCreateTime).reversed())
            .collect(Collectors.toList());
        
        return PageUtils.paginateList(filteredData, current, size);
    }
    
    /**
     * 多条件动态查询
     */
    public IPage<YourEntity> dynamicQueryPage(List<YourEntity> dataList, 
                                             long current, long size,
                                             DynamicQuery query) {
        
        Stream<YourEntity> stream = dataList.stream();
        
        // 动态添加过滤条件
        if (StringUtils.hasText(query.getKeyword())) {
            stream = stream.filter(item -> 
                item.getName().contains(query.getKeyword()));
        }
        
        if (query.getStartDate() != null) {
            stream = stream.filter(item -> 
                !item.getCreateTime().before(query.getStartDate()));
        }
        
        List<YourEntity> filteredList = stream.collect(Collectors.toList());
        
        return PageUtils.paginateList(filteredList, current, size);
    }
    
    private boolean filterCondition(YourEntity item, Map<String, Object> filters) {
        // 实现你的过滤逻辑
        return true;
    }
}

前端调用示例

html 复制代码
// Vue/React 调用示例
const getPageData = async (page = 1, page pageSize = 10) => {
    try {
        const response = await axios.get('/api/data/page', {
            params: {
                current: page,
                size: pageSize
            }
        });
        
        const pageInfo = response.data.data;
        console.log('当前页:', pageInfo.current);
        console.log('每页大小:', pageInfo.size);
        console.log('总记录数:', pageInfo.total);
        console.log('总页数:', pageInfo.pages);
        console.log('数据列表:', pageInfo.records);
    } catch (error) {
        console.error('请求失败:', error);
    }
};

关键要点总结

1、性能考虑:对于大数据集,建议缓存分页计算结果

2、线程安全:如果源 List 可能被并发修改,需要加锁或使用副本

3、空值处理:处理好边界情况(如超出范围的页码)

4、灵活性:可根据需要添加排序、过滤等功能

推荐使用方案一或方案二,它们结构清晰且易于维护,同时保持了与 MyBatis-Plus 的良好兼容性。

相关推荐
bing_15844 分钟前
Spring Boot 项目中判断集合(List、Set、Map)不能为空且不为 null的注解使用
spring boot·后端·list
星轨初途1 小时前
数据结构排序算法详解(2)——选择排序(附动图)
c语言·数据结构·经验分享·笔记·b树·算法·排序算法
Chance_to_win3 小时前
数据结构之排序
数据结构
小年糕是糕手3 小时前
【C++】类和对象(二) -- 构造函数、析构函数
java·c语言·开发语言·数据结构·c++·算法·leetcode
kupeThinkPoem4 小时前
跳表有哪些算法?
数据结构·算法
前端小L4 小时前
图论专题(二十一):并查集的“工程应用”——拔线重连,修复「连通网络」
数据结构·算法·深度优先·图论·宽度优先
前端小L4 小时前
图论专题(二十三):并查集的“数据清洗”——解决复杂的「账户合并」
数据结构·算法·安全·深度优先·图论
啊董dong5 小时前
课后作业-2025年11月23号作业
数据结构·c++·算法·深度优先·noi
dlz08365 小时前
从架构到数据结构,到同步逻辑,到 show run 流程优化
数据结构
jllws16 小时前
数据结构_字符和汉字的编码与查找
数据结构