在平常开发过程中,我们经常会遇到截取列表片段的需求,比如取列表中前4个元素、取后四个元素。Java的List
提供了subList
方法,可以用来完成这些工作,但是使用起来并没有那么便利,比如取前四个元素:
list.subList(0, 4)
这里代码的本意是“取出列表中下标为0到4(不包括4)的元素”,结果恰好与需求相同,但是表达并非最直观。再来看取最后4个元素的版本:
int size = list.size();
list.subList(size - 4 ,size)
呃…更不直观了。我每次写这段程序都得小心翼翼检查index是否正确。
于是就有了本文要介绍的两个工具方法:first
和last
。
API介绍
-
first
方法签名:static <T> List<T> first(List<T> list, int n)
功能:获取列表list
中前n
个元素,如果列表长度小于n
,抛出异常。 -
firstAtMost
方法签名:static <T> List<T> firstAtMost(List<T> list, int n)
功能:获取列表list
中最多前n
个元素,如果列表长度小于n
,返回list
的一个副本。 -
last
方法签名:static <T> List<T> last(List<T> list, int n)
功能:获取列表list
中最后n
个元素,如果列表长度小于n
,抛出异常。 -
lastAtMost
方法签名:static <T> List<T> lastAtMost(List<T> list, int n)
功能:获取列表list
中最多前n
个元素,如果列表长度小于n
,返回list
的一个副本。
使用示例
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7);
List<Integer> first = first(list, 3);//{1, 2, 3}
List<Integer> atMostFirstList = firstAtMost(list, 3);//{1, 2, 3}
List<Integer> list1 = firstAtMost(list, 10);//{1, 2, 3, 4, 5, 6, 7}
List<Integer> last = last(list, 3);//{5, 6, 7}
List<Integer> lastAtMost = lastAtMost(list, 3);//{5, 6, 7}
List<Integer> last2 = lastAtMost(list, 30);//{1, 2, 3, 4, 5, 6, 7}
功能实现
public static int size(@Nullable Collection<?> collection) {
return collection == null ? 0 : collection.size();
}
public static <T> List<T> first(List<T> list, int n) {
if (size(list) < n) {
throw new IllegalArgumentException("list size less than " + n);
} else {
return new ArrayList<>(list.subList(0, n));
}
}
public static <T> List<T> firstAtMost(List<T> list, int n) {
int size = size(list);
return size == 0
? new ArrayList<>()
: new ArrayList<>(size <= n ? list : list.subList(0, n));
}
public static <T> List<T> last(List<T> list, int n) {
int size = size(list);
if (size < n) {
throw new IllegalArgumentException("list size less than " + n);
} else {
return new ArrayList<>(list.subList(size - n, size));
}
}
public static <T> List<T> lastAtMost(List<T> list, int n) {
int size = size(list);
return size == 0
? new ArrayList<>()
: new ArrayList<>(size <= n ? list : list.subList(size - n, size));
}