如何在Java 8中对对象列表进行分页? [英] How to paginate a list of objects in Java 8?

查看:501
本文介绍了如何在Java 8中对对象列表进行分页?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

给定 java.util.List ,其中 n 元素和所需的页面大小 m ,我想将其转换为包含 n / m + n%m 元素的地图。每个地图元素应包含 m 元素。

Given a java.util.List with n elements and a desired page size m, I want to transform it to a map containing n/m+n%m elements. Each map element shall contain m elements.

以下是整数示例:

    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吗?

Is this possible, using Java 8?

推荐答案

您可以使用 IntStream.iterate 结合 toMap 收集器和列表上的 subList 方法(感谢 Duncan 用于简化)。

You could use IntStream.iterate combined with the toMap collector and the subList method on List (thanks to Duncan for the simplifications).

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 给出(这将是流的限制)。

You first calculate the numbers of keys you need in the map. This is given by (list.size() + pageSize - 1) / pageSize (this will be the limit of the stream).

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

Then you create a Stream that creates the sequence 0, pageSize, 2* pageSize, ....

现在为每个值 i 你获取相应的 subList 这将是我们的值(您需要额外检查最后的 subList ,以便不越界),您为此映射相应的键,该序列将是序列 0 / pageSize,pageSize / pageSize,2 * pageSize / pageSize 除以 pageSize 以获得自然序列 0,1,2,...

Now for each value i you grab the corresponding subList which will be our value (you need an additional check for the last subList for not getting out of bounds) for which you map the corresponding key which will be the sequence 0/pageSize, pageSize/pageSize, 2*pageSize/pageSize that you divide by pageSize to get the natural sequence 0, 1, 2, ....

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

The pipeline can be safely run in parallel (you may need to use the toConcurrentMap collector instead). As Brian Goetz commented (thanks for reminding me that), iterate is not worth if you want to parallelize the stream, so here's a version with 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个元素,您将得到以下序列:


So as with your example (a list of 10 elements with a page size of 3), you'll get the following sequence:

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

0, 3, 6, 9, 12, 15, ... that you limit to (10 + 3 - 1) / 3 = 12 / 3 = 4, which let the sequence 0, 3, 6, 9. Now each value is mapped to its corresponding sublist:

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(","))

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

which just collect the elements separated by a comma into a single String.

这篇关于如何在Java 8中对对象列表进行分页?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆