Two usage postures for paging traversal in Java
Paging through iterative scenarios is common in daily development, such as scanning tables, retrieving 100 pieces of data at a time, and then iterating through those 100 pieces of data, executing some business logic in turn. After the 100 pieces are executed, another 100 pieces of data are loaded until the scan is complete
So what can we do to implement the paging iteration scenario above
This article will introduce two kinds of use posture
- General usage
- Use Iterator’s gestures
1. Data query simulation
First mock the logic of fetching data in a single page, generate data directly randomly, and control the return of up to three pages
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;
}
Copy the code
2. Basic implementation
For this scenario, the most common and easiest and intuitive implementation
- The while loop
- Internal traversal
private static void scanByNormal(a) {
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(); }}Copy the code
3. Implementation of iterator
A more interesting way to use iterator traversal is to first define a generic page iterator
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(a) {}@Override
public boolean hasNext(a) {
if(list ! =null && list.size() > currentIndex) {
return true;
}
// The current data has been loaded, try to load the next batch
if(! hasMore) {return false;
}
list = load(start, size);
if (list == null || list.isEmpty()) {
// No data is loaded, end
return false;
}
if (list.size() < size) {
// The number of returns is less than the limit number, indicating that more data can be loaded
hasMore = false;
}
currentIndex = 0;
start += list.size();
return true;
}
@Override
public T next(a) {
return list.get(currentIndex++);
}
public abstract List<T> load(int start, int size);
}
Copy the code
Next, we can implement our requirements with the help of the above iterator
private static void scanByIterator(a) {
MyIterator<String> iterator = new MyIterator<String>() {
@Override
public List<String> load(int start, int size) {
returnrandStr(start, size); }};while(iterator.hasNext()) { String str = iterator.next(); System.out.println(str); }}Copy the code
So the question comes, what is the advantage of using the above way over the previous one?
- Double cycle to single cycle
Coming to the point, jdK1.8 introduced the function method + lambda to provide a more concise usage posture
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(a) {
if(list ! =null && list.size() > currentIndex) {
return true;
}
// The current data has been loaded, try to load the next batch
if(! hasMore) {return false;
}
list = loadFunc.load(start, size);
if (list == null || list.isEmpty()) {
// No data is loaded, end
return false;
}
if (list.size() < size) {
// The number of returns is less than the limit number, indicating that more data can be loaded
hasMore = false;
}
currentIndex = 0;
start += list.size();
return true;
}
@Override
public T next(a) {
returnlist.get(currentIndex++); }}}Copy the code
Using gestures in jdk1.8 and later is a single line of code
private static void scanByIteratorInJdk8(a) {
new MyIterator<>(IteratorTestForJdk18::randStr)
.forEachRemaining(System.out::println);
}
Copy the code
This comparison is not very noticeable, from now on paging iteration through no longer long double iteration
II. The other
1. A gray Blog:liuyueyi.github.io/hexblog
A gray personal blog, recording all the study and work in the blog, welcome everyone to go to stroll
2. Statement
As far as the letter is not as good, the above content is purely one’s opinion, due to the limited personal ability, it is inevitable that there are omissions and mistakes, if you find bugs or have better suggestions, welcome criticism and correction, don’t hesitate to appreciate
- Micro Blog address: Small Gray Blog
- QQ: a gray /3302797840
- Wechat official account: One Grey Blog