gpt4 book ai didi

java - 如何对 Java 8 中的对象列表进行分页?

转载 作者:搜寻专家 更新时间:2023-10-30 19:42:30 25 4
gpt4 key购买 nike

给定一个包含 n 元素的 java.util.List 和所需的页面大小 m,我想将其转换为包含以下内容的 map n/m+n%m 个元素。每个 map 元素应包含 m 个元素。

这是一个整数的例子:

    List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);

// What is the equivalent Java 8 code to create the map below from my list?

Map<Integer, List<Integer>> map = new HashMap<>();
map.put(0, Arrays.asList(1,2,3));
map.put(1, Arrays.asList(4,5,6));
map.put(2, Arrays.asList(7,8,9));
map.put(3, Arrays.asList(10));

使用 Java 8 这可能吗?

最佳答案

你可以使用 IntStream.iterate结合 toMap Collection 家和 subList List 上的方法(感谢 Duncan 的简化)。

import static java.util.stream.Collectors.toMap;
import static java.lang.Math.min;

...

static Map<Integer, List<Integer>> partition(List<Integer> list, int pageSize) {
return IntStream.iterate(0, i -> i + pageSize)
.limit((list.size() + pageSize - 1) / pageSize)
.boxed()
.collect(toMap(i -> i / pageSize,
i -> list.subList(i, min(i + pageSize, list.size()))));
}

您首先计算 map 中所需的键数。这是由 (list.size() + pageSize - 1) / pageSize 给出的(这将是流的限制)。

然后您创建一个 Stream 来创建序列 0, pageSize, 2* pageSize, ... .

现在对于每个值 i你抢对应的subList这将是我们的值(您需要对最后一个 subList 进行额外检查,以确保没有越界),您为其映射相应的键,这将是序列 0/pageSize, pageSize/pageSize, 2*pageSize/pageSize你除以 pageSize得到自然序列0, 1, 2, ... .

管道可以安全地并行运行(您可能需要改用 toConcurrentMap 收集器)。正如 Brian Goetz 评论的那样(感谢您提醒我),iterate如果你想并行化流是不值得的,所以这里有一个版本 range .

return IntStream.range(0, (list.size() + pageSize - 1) / pageSize)
.boxed()
.collect(toMap(i -> i ,
i -> list.subList(i * pageSize, min(pageSize * (i + 1), list.size()))));

因此对于您的示例(页面大小为 3 的 10 个元素的列表),您将获得以下序列:

0, 3, 6, 9, 12, 15, ...您限制为 (10 + 3 - 1) / 3 = 12 / 3 = 4 , 这让序列 0, 3, 6, 9 .现在每个值都映射到其对应的子列表:

0 / pageSize = 0 -> list.subList(0, min(0 + pageSize, 10)) = list.subList(0, 3);
3 / pageSize = 1 -> list.subList(3, min(3 + pageSize, 10)) = list.subList(3, 6);
6 / pageSize = 2 -> list.subList(6, min(6 + pageSize, 10)) = list.subList(6, 9);
9 / pageSize = 3 -> list.subList(9, min(9 + pageSize, 10)) = list.subList(6, 10);
^
|
this is the edge-case for the last sublist to
not be out of bounds


如果你真的想要 Map<Integer, String>您可以将值映射器函数替换为

import static java.util.stream.Collectors.joining;

...

i -> list.subList(i, min(i + pageSize, list.size()))
.stream()
.map(Object::toString)
.collect(joining(","))

它只是将以逗号分隔的元素收集到一个字符串中。

关于java - 如何对 Java 8 中的对象列表进行分页?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29273705/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com