如何使用 subList()

我有一个显示 Glassfish 日志文件列表的 JSF 页面。我使用延迟加载分页。我将日志文件名列表保存在 JavaList中。

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?我想如果我想得到索引从30到40,但如果只有35个索引得到只有5。

157030 次浏览

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

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

例如,检查 size,它返回35,因此调用 sublist(30, size());

或者

抄自 pb2q 评论

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

要获取最后一个元素,只需使用列表的大小作为第二个参数。例如,如果你有35个文件,你想要最后5个,你会这样做:

dataList.subList(30, 35);

保证安全的方法是:

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

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

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);
}

你可以在 Java8中使用流:

dataList.stream().skip(5).limit(10).collect(Collectors.toList());
dataList.stream().skip(30).limit(10).collect(Collectors.toList());

尽管可能为时已晚,但我建议在 Java8中使用 stream,以避免手动处理出界异常。

这个密码

dataList = dataList.stream().skip(30).limit(8).collect(Collectors.toList());

工作原理与

dataList = dataList.subList(30, 38);

在超出索引错误的情况下,dataList 将为空列表,而不是抛出任何异常。

对于 Kotlin 你可以用: myList.subList(min, max.coerceAtMost(myList.size)

或者根据上面的问题: myList.subList(30, 38.coerceAtMost(myList.size)