1. 概述
在这个简短的教程中,我们将学习如何在使用List
接口提供的subList()
方法时避免IndexOutOfBoundsException
。首先,我们将讨论subList()
的工作原理,然后在实践中看到如何重现并修复这个异常。
2. 了解异常
通常,Collections API提供了subList(int fromIndex, int toIndex)
方法,用于返回给定列表的一部分。返回的部分包括指定的fromIndex
和toIndex
之间的所有元素。需要注意的是,fromIndex
始终是包含的,而toIndex
则是不包含的。
subList()
方法的特性是,当给定的fromIndex
和endIndex
有问题时,会抛出IndexOutOfBoundsException
作为信号。
简单来说,IndexOutOfBoundsException
意味着越界,当fromIndex
严格小于0、严格大于toIndex
,或者toIndex
大于列表长度时,就会抛出这个异常。
3. 实践示例
现在让我们看看subList()
方法的实际应用。为了简化,我们创建一个测试来重现IndexOutOfBoundsException
:
@Test
void whenCallingSuListWithIncorrectIndexes_thenThrowIndexOutOfBoundsException() {
List<String> cities = List.of("Tokyo", "Tamassint", "Paris", "Madrid", "London");
assertThatThrownBy(() -> cities.subList(6, 10)).isInstanceOf(IndexOutOfBoundsException.class);
}
如图所示,测试因为提供了一个大于列表长度的toIndex
参数(10)而失败,抛出了IndexOutOfBoundsException
。
4. 解决异常
修复异常最简单的方法是在调用subList()
方法之前对指定的fromIndex
和toIndex
进行验证:
static List<String> safeSubList(List<String> myList, int fromIndex, int toIndex) {
if (myList == null || fromIndex >= myList.size() || toIndex <= 0 || fromIndex >= toIndex) {
return Collections.emptyList();
}
return myList.subList(Math.max(0, fromIndex), Math.min(myList.size(), toIndex));
}
如上所示,我们的替代方法是安全的。如果给定的fromIndex
大于或等于列表大小或给定的toIndex
,则返回空列表。同样,如果指定的toIndex
小于或等于0,也返回空列表。如果fromIndex
小于0,我们将0
作为fromIndex
参数传递。另一方面,如果传递的toIndex
参数大于列表大小,我们将设置列表大小为新的toIndex
。
现在,让我们添加另一个测试用例来验证我们的新方法是否有效:
@Test
void whenCallingSafeSuList_thenReturnData() {
List<String> cities = List.of("Amsterdam", "Buenos Aires", "Dublin", "Brussels", "Prague");
assertThat(SubListUtils.safeSubList(cities, 6, 10)).isEmpty();
assertThat(SubListUtils.safeSubList(cities, -2, 3)).containsExactly("Amsterdam", "Buenos Aires", "Dublin");
assertThat(SubListUtils.safeSubList(cities, 3, 20)).containsExactly("Brussels", "Prague");
}
正如预期的那样,我们的subList()
方法的安全版本可以处理任何指定的fromIndex
和toIndex
。
5. 总结
在这篇短文中,我们讨论了如何在使用subList()
方法时避免IndexOutOfBoundsException
。过程中,我们了解了导致subList()
抛出异常的原因,并学会了如何在实践中重现和修复它。如往常一样,示例的完整源代码可以在GitHub上找到。