dou*_*e07 7 java iteration collections paging guava
我传递了一个对象集合(在我的情况下是一些Contact类),需要从该集合返回一个页面.我的代码感觉比它需要的时间长得多.我是否缺少一些可以执行更优雅的库,而不是像下面一样一次迭代每个元素?
protected Collection<Contact> getPageOfContacts(
Collection<Contact> contacts, int pageIndex, int pageSize) {
if (pageIndex < 0 || pageSize <= 0
|| pageSize > contacts.size()) {
return contacts;
}
int firstElement = pageIndex * pageSize;
int lastElement = (pageIndex + 1) * pageSize - 1;
Collection<Contact> pagedContacts = new ArrayList<Contact>();
int index = -1;
for (Contact contact : contacts) {
index++;
if (index < firstElement) {
continue;
}
if (index > lastElement) {
break;
}
pagedContacts.add(contact);
}
return pagedContacts;
}
Run Code Online (Sandbox Code Playgroud)
Tho*_*ung 12
你可以使用Guava Iterables.partition:
protected <T> Collection<T> getPageOfContacts(
Collection<T> contacts, int pageIndex, int pageSize) {
return Lists.newArrayList(
Iterables.partition(contacts, pageSize)).get(pageIndex);
}
Run Code Online (Sandbox Code Playgroud)
更复杂的版本不会创建所有页面来选择正确的页面,但会在找到正确的页面时停止.
protected <T> Collection<T> getPageOfContacts(
Collection<T> contacts, int pageIndex, int pageSize) {
Iterator<List<T>> partitions = Iterators.partition(contacts.iterator(), pageSize);
for(int page = 0; page<pageSize && partitions.hasNext(); page++){
List<T> partition = partitions.next();
if(page == pageIndex) return partition;
}
return Collections. <T> emptyList(); //or fail
}
Run Code Online (Sandbox Code Playgroud)
更新:
感谢ColinD指出:
Iterables.get(Iterables.partition(contacts, pageSize), pageIndex)
Run Code Online (Sandbox Code Playgroud)
是一个更简单的实现.
如果您可以要求将数据分页为a List
,则可以使用Guava轻松获取单个页面的子列表视图:
public <T> List<T> getPage(List<T> list, int pageIndex, int pageSize) {
return Lists.partition(list, pageSize).get(pageIndex);
}
Run Code Online (Sandbox Code Playgroud)
这不涉及复制或迭代(它使用原始列表的子列表视图)并处理pageSize
透明度少于元素的最终页面.
对于任意Iterable
或Collection
,我会这样做:
public <T> List<T> getPage(Iterable<T> iterable, int pageIndex, int pageSize) {
return Iterables.get(Iterables.partition(iterable, pageSize), pageIndex);
}
Run Code Online (Sandbox Code Playgroud)
通过提供这两种方法,您将能够在编译时有效地处理已知为列表的对象,并且能够尽可能高效地处理任何其他类型的对象Iterable
.