詳解Java中兩種分頁(yè)遍歷的使用姿勢(shì)
在日常開(kāi)發(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)也是最簡(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種方式
相關(guān)文章
手把手教你使用Java實(shí)現(xiàn)在線生成pdf文檔
在實(shí)際的業(yè)務(wù)開(kāi)發(fā)的時(shí)候,常常會(huì)需要把相關(guān)的數(shù)據(jù)信息,通過(guò)一些技術(shù)手段生成對(duì)應(yīng)的PDF文件,然后返回給用戶。本文將手把手教大家如何利用Java實(shí)現(xiàn)在線生成pdf文檔,需要的可以參考一下2022-03-03
為什么說(shuō)要慎用SpringBoot @ComponentScan
本文主要介紹了為什么說(shuō)要慎用SpringBoot @ComponentScan,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-07-07
Java多線程通訊之wait,notify的區(qū)別詳解
這篇文章主要介紹了Java多線程通訊之wait,notify的區(qū)別詳解,非常不錯(cuò),具有一定的參考借鑒借鑒價(jià)值,需要的朋友可以參考下2018-07-07
Java 獲取當(dāng)前時(shí)間及實(shí)現(xiàn)時(shí)間倒計(jì)時(shí)功能【推薦】
這篇文章主要介紹了Java 獲取當(dāng)前時(shí)間及實(shí)現(xiàn)時(shí)間倒計(jì)時(shí)功能 ,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-05-05
常用校驗(yàn)注解之@NotNull,@NotBlank,@NotEmpty的區(qū)別及說(shuō)明
這篇文章主要介紹了常用校驗(yàn)注解之@NotNull,@NotBlank,@NotEmpty的區(qū)別及說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-01-01

