詳解Java中兩種分頁(yè)遍歷的使用姿勢(shì)
在日常開發(fā)中,分頁(yè)遍歷迭代的場(chǎng)景可以說(shuō)非常普遍了,比如掃表,每次撈100條數(shù)據(jù),然后遍歷這100條數(shù)據(jù),依次執(zhí)行某個(gè)業(yè)務(wù)邏輯;這100條執(zhí)行完畢之后,再加載下一百條數(shù)據(jù),直到掃描完畢
那么要實(shí)現(xiàn)上面這種分頁(yè)迭代遍歷的場(chǎng)景,我們可以怎么做呢
本文將介紹兩種使用姿勢(shì)
- 常規(guī)的使用方法
- 借助Iterator的使用姿勢(shì)
1. 數(shù)據(jù)查詢模擬
首先mock一個(gè)分頁(yè)獲取數(shù)據(jù)的邏輯,直接隨機(jī)生成數(shù)據(jù),并且控制最多返回三頁(yè)
public static int cnt = 0;
private static List<String> randStr(int start, int size) {
++cnt;
if (cnt > 3) {
return Collections.emptyList();
} else if (cnt == 3) {
cnt = 0;
size -= 2;
}
System.out.println("======================= start to gen randList ====================");
List<String> ans = new ArrayList<>(size);
for (int i = 0; i < size; i++) {
ans.add((start + i) + "_" + UUID.randomUUID().toString());
}
return ans;
}
2. 基本實(shí)現(xiàn)方式
針對(duì)這種場(chǎng)景,最常見也是最簡(jiǎn)單直觀的實(shí)現(xiàn)方式
- while死循環(huán)
- 內(nèi)部遍歷
private static void scanByNormal() {
int start = 0;
int size = 5;
while (true) {
List<String> list = randStr(start, size);
for (String str : list) {
System.out.println(str);
}
if (list.size() < size) {
break;
}
start += list.size();
}
}
3. 迭代器實(shí)現(xiàn)方式
接下來(lái)介紹一種更有意思的方式,借助迭代器的遍歷特性來(lái)實(shí)現(xiàn),首先自定義一個(gè)通用分頁(yè)迭代器
public static abstract class MyIterator<T> implements Iterator<T> {
private int start = 0;
private int size = 5;
private int currentIndex;
private boolean hasMore = true;
private List<T> list;
public MyIterator() {
}
@Override
public boolean hasNext() {
if (list != null && list.size() > currentIndex) {
return true;
}
// 當(dāng)前的數(shù)據(jù)已經(jīng)加載完畢,嘗試加載下一批
if (!hasMore) {
return false;
}
list = load(start, size);
if (list == null || list.isEmpty()) {
// 沒(méi)有加載到數(shù)據(jù),結(jié)束
return false;
}
if (list.size() < size) {
// 返回條數(shù)小于限制條數(shù),表示還有更多的數(shù)據(jù)可以加載
hasMore = false;
}
currentIndex = 0;
start += list.size();
return true;
}
@Override
public T next() {
return list.get(currentIndex++);
}
public abstract List<T> load(int start, int size);
}
接下來(lái)借助上面的迭代器可以比較簡(jiǎn)單的實(shí)現(xiàn)我們的需求了
private static void scanByIterator() {
MyIterator<String> iterator = new MyIterator<String>() {
@Override
public List<String> load(int start, int size) {
return randStr(start, size);
}
};
while (iterator.hasNext()) {
String str = iterator.next();
System.out.println(str);
}
}
那么問(wèn)題來(lái)了,上面這種使用方式比前面的優(yōu)勢(shì)體現(xiàn)再哪兒呢?
雙層循環(huán)改為單層循環(huán)
接下來(lái)接入重點(diǎn)了,在jdk1.8引入了函數(shù)方法 + lambda之后,又提供了一個(gè)更簡(jiǎn)潔的使用姿勢(shì)
public class IteratorTestForJdk18 {
@FunctionalInterface
public interface LoadFunc<T> {
List<T> load(int start, int size);
}
public static class MyIterator<T> implements Iterator<T> {
private int start = 0;
private int size = 5;
private int currentIndex;
private boolean hasMore = true;
private List<T> list;
private LoadFunc<T> loadFunc;
public MyIterator(LoadFunc<T> loadFunc) {
this.loadFunc = loadFunc;
}
@Override
public boolean hasNext() {
if (list != null && list.size() > currentIndex) {
return true;
}
// 當(dāng)前的數(shù)據(jù)已經(jīng)加載完畢,嘗試加載下一批
if (!hasMore) {
return false;
}
list = loadFunc.load(start, size);
if (list == null || list.isEmpty()) {
// 沒(méi)有加載到數(shù)據(jù),結(jié)束
return false;
}
if (list.size() < size) {
// 返回條數(shù)小于限制條數(shù),表示還有更多的數(shù)據(jù)可以加載
hasMore = false;
}
currentIndex = 0;
start += list.size();
return true;
}
@Override
public T next() {
return list.get(currentIndex++);
}
}
}
在jdk1.8及之后的使用姿勢(shì),一行代碼即可
private static void scanByIteratorInJdk8() {
new MyIterator<>(IteratorTestForJdk18::randStr)
.forEachRemaining(System.out::println);
}
這次對(duì)比效果是不是非常顯眼了,從此以后分頁(yè)迭代遍歷再也不用冗長(zhǎng)的雙重迭代了
到此這篇關(guān)于詳解Java中兩種分頁(yè)遍歷的使用姿勢(shì)的文章就介紹到這了,更多相關(guān)Java 分頁(yè)遍歷內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Java Web 簡(jiǎn)單的分頁(yè)顯示實(shí)例代碼
- Java的MyBatis框架中實(shí)現(xiàn)多表連接查詢和查詢結(jié)果分頁(yè)
- 舉例詳解用Java實(shí)現(xiàn)web分頁(yè)功能的方法
- 使用Jquery+Ajax+Json如何實(shí)現(xiàn)分頁(yè)顯示附JAVA+JQuery實(shí)現(xiàn)異步分頁(yè)
- js前臺(tái)分頁(yè)顯示后端JAVA數(shù)據(jù)響應(yīng)
- java中利用List的subList方法實(shí)現(xiàn)對(duì)List分頁(yè)(簡(jiǎn)單易學(xué))
- JavaWeb中的簡(jiǎn)單分頁(yè)完整代碼(推薦)
- Java分頁(yè)查詢--分頁(yè)顯示(實(shí)例講解)
- Java實(shí)現(xiàn)簡(jiǎn)單的分頁(yè)功能
- Java使用MyBatis框架分頁(yè)的5種方式
mybatis-plus實(shí)體類中出現(xiàn)非數(shù)據(jù)庫(kù)映射字段解決辦法
SpringMVC源碼解析之消息轉(zhuǎn)換器HttpMessageConverter
谷歌二維碼引擎com.google.zxing二維碼生成與解析
java數(shù)據(jù)結(jié)構(gòu)之樹基本概念解析及代碼示例
Springboot集成JUnit5優(yōu)雅進(jìn)行單元測(cè)試的示例

