如何使用subList()


79

我有一个JSF页面,其中显示了Glassfish日志文件列表。我使用延迟加载进行分页。我将日志文件名称列表保存在Java中List

private List<directoryListObj> dataList = new ArrayList<>();

dataList = dataList.subList(firstRow, lastRow);

这就是问题所在。例如,我有35个文件进入目录。当我这样做时

dataList = dataList.subList(5, 15);

它工作正常。但是当我这样做时:

dataList = dataList.subList(30, 38);

我得到了错误的错误索引,因为我想获取List之外的索引。例如,我如何返回30到35的List元素?我想让索引从30增加到40,但如果只有35个索引就只能得到5。


13
dataList = dataList.subList(30, 38 > dataList.size() ? dataList.size() : 38);
2012年

18
dataList.subList(30, Math.min(38, dataList.size())
Ismail Badawi

1
@ pb2q似乎您失去了答案的机会。
路易吉·门多萨

如果看一下APIdoc,您会注意到它会抛出IndexOutOfBoundsException - endpoint index value out of range (fromIndex < 0 || toIndex > size)。因此,将来请查看APIdoc以获得此类提示。
zeller 2012年

Answers:


96

使用subList(30, 38);将失败,因为最大索引38在列表中不可用,因此不可能。

唯一的方法可能是在请求子列表之前,您可以使用列表size()方法显式确定最大索引。

例如,检查尺寸,它返回35,所以调用 sublist(30, size());

要么

复制自pb2q评论

dataList = dataList.subList(30, 38 > dataList.size() ? dataList.size() : 38);

6
如果列表少于30个项目,那也将失败。
Haroldo_OK 2015年

@Haroldo_OK:是的,您是正确的,但假设列表中包含30多个项目。
科萨2015年

3
我更喜欢dataList = dataList.subList(30, Math.min(38, dataList.size()));
Benny Bottema

46

我已经实现并测试了这一点;它应该涵盖大多数基础:

public static <T> List<T> safeSubList(List<T> list, int fromIndex, int toIndex) {
    int size = list.size();
    if (fromIndex >= size || toIndex <= 0 || fromIndex >= toIndex) {
        return Collections.emptyList();
    }

    fromIndex = Math.max(0, fromIndex);
    toIndex = Math.min(size, toIndex);

    return list.subList(fromIndex, toIndex);
}

4
这应该是公认的答案,这是唯一一个愿意测试其代码的人。
Ed Randall

2
非常有帮助,谢谢。将其分解为一种方法比尝试在三元运算符中包装逻辑要有意义得多,以这种方式很难理解。
史蒂夫(Steve)

43

要获取最后一个元素,只需使用列表的大小作为第二个参数。因此,例如,如果您有35个文件,并且想要最后五个文件,则可以执行以下操作:

dataList.subList(30, 35);

保证安全的方法是:

dataList.subList(Math.max(0, first), Math.min(dataList.size(), last) );

4
如果“第一个”大于列表大小,那也将失败。
Haroldo_OK 2015年

3
@Haroldo_OK:或是否last为负!
Tagir Valeev 2015年

如果first >= last
augurar

7

您可以在Java 8中使用流。要始终最多获得10个条目,可以执行以下操作:

dataList.stream().skip(5).limit(10).collect(Collectors.toList());
dataList.stream().skip(30).limit(10).collect(Collectors.toList());
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.