如何在Java 8中对对象列表进行分页?
给定一个java.util.List
with
n
元素和所需的页面大小m
,我想将其转换为包含n/m+n%m
元素的地图。每个地图元素应包含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
收集器和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()))));
}
首先,您需要计算地图中所需的键数。这是通过(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>
,可以将value mapper函数替换为
import static java.util.stream.Collectors.joining;...
i -> list.subList(i, min(i + pageSize, list.size()))
.stream()
.map(Object::toString)
.collect(joining(","))
只是将用逗号分隔的元素收集到单个String中。
以上是 如何在Java 8中对对象列表进行分页? 的全部内容, 来源链接: utcz.com/qa/425822.html