jdk源码阅读之 java.util.Iterator
2016-12-18 21:52
423 查看
作用
Itarator是一个泛型接口,主要描述遍历的手段, 需要实现两个方法
hasNext,
next
hasNext方法 返回一个
boolean用来描述是否还有下一个
next方法 用来返回下一个值
iterator的使用方式应该总是先用
hasNext来判断是否有更多的内容, 然后再用
next来获取下一条数据
使用
通过实现一个数据库表记录迭代器TableDataIterator来加强印象
实现要求
约定:表必须包含名为
id的列
id必须为自增整数
通过传入表名后能够将整张表的数据都遍历出来
实现
import java.sql.*; import java.util.*; /** * Created by 0x0001 on 16/12/18. */ public class TableDataIterator implements Iterator<Map<String, Object>> { // 表名 private final String tableName; // 缓存数据条数 private final int bufSize = 20; // 上一次最后一条记录的ID private int prevID = 0; private final List<Map<String, Object>> buffers; static { // 加载数据库驱动 try { Class.forName("driver class full name"); } catch(Exception e) { throw new RuntimeException(e); } } public TableDataIterator(String tableName) { this.tableName = tableName; buffers = new ArrayList<>(); } @Override public boolean hasNext() { // 如果缓存不为空则允许迭代, 否则尝试加载数据到缓存 return !buffers.isEmpty() || loadToCache(); } @Override public Map<String, Object> next() { if (hasNext()) { return buffers.remove(0); } throw new IllegalStateException("no more data"); } private boolean loadToCache() { String sql = "SELECT * FROM " + tableName + " WHERE id > ? ORDER BY id ASC LIMIT ?"; try (Connection conn = getConnection()) { try(PreparedStatement pstmt = conn.prepareStatement(sql)) { pstmt.setObject(1, prevID); pstmt.setObject(2, bufSize); try (ResultSet rs = pstmt.executeQuery()) { while (rs.next()) { buffers.add(rs2Map(rs)); } // 数据加载到buf以后顺便设置当前已经获取到的数据的最后一条的id if (!buffers.isEmpty()) { Map<String, Object> last = buffers.get(buffers.size() -1); prevID = (Integer) last.get("id"); } } } } catch(SQLException e) { throw new RuntimeException(e); } return !buffers.isEmpty(); } private Connection getConnection() { try { return DriverManager.getConnection("jdbc_url"); } catch (SQLException e) { throw new RuntimeException(e); } } private Map<String, Object> rs2Map(ResultSet rs) { try { ResultSetMetaData metaData = rs.getMetaData(); int columnCount = metaData.getColumnCount(); Map<String, Object> row = new HashMap<String, Object>(); for (int i = 0; i < columnCount; i++) { String name = metaData.getColumnName(i); Object data = rs.getObject(i); row.put(name, data); } return row; } catch (SQLException e) { throw new RuntimeException(e); } } public static void main(String[] args) { Iterator<Map<String, Object>> iterator = new TableDataIterator("user"); while(iterator.hasNext()) { System.out.println(iterator.next()); } } }
配合
Iterable能实现一个可以使用
for-each循环的迭代器, 如:
class TableDataIterable implements Iterable<Map<String, Object>> { private final String tableName; TableDataIterable(String tableName) { this.tableName = tableName; } @Override public Iterator<Map<String, Object>> iterator() { return new TableDataIterator(tableName); } public static void main(String[] args) { for(Map<String, Object> row : new TableDataIterable("user")) { System.out.println(row); } } }
使用起来将更加方便,
for-each循环被jdk编译后代码应该大致如下:
Iterator<Map<String, Object>> iterator = new TableDataIterable("user").iterator(); while(iterator.hasNext()) { System.out.println(iterator.next()); }
相关文章推荐
- jdk源码阅读之 java.util.Collection
- Jdk源码阅读之Java.util.concurrent
- JDK源码阅读—基本集合类(java.util)
- 《java.util.concurrent 包源码阅读》01 源码包的结构
- java类库的阅读笔记_jdk1.7.0_40_java.util.HashMap
- 《java.util.concurrent 包源码阅读》03 锁
- 《java.util.concurrent 包源码阅读》11 线程池系列之ThreadPoolExecutor 第一部分
- 《java.util.concurrent 包源码阅读》15 线程池系列之ScheduledThreadPoolExecutor 第二部分
- 《java.util.concurrent 包源码阅读》09 线程池系列之介绍篇
- java JDK源码中的Iterator
- 《java.util.concurrent 包源码阅读》10 线程池系列之AbstractExecutorService
- java类库的阅读笔记_jdk1.7.0_40_java.util.concurrent.locks.AbstractQueuedSynchronizer
- 《java.util.concurrent 包源码阅读》06 ArrayBlockingQueue
- JDK源码分析——Java.util.Vector的浅析
- java类库的阅读笔记_jdk1.7.0_40_java.util.ArrayList
- java类库的阅读笔记_jdk1.7.0_40_java.util.concurrent.ConcurrentHashMap
- java类库的阅读笔记_jdk1.7.0_40_java.util.Timer
- 《java.util.concurrent 包源码阅读》07 LinkedBlockingQueue
- 《java.util.concurrent 包源码阅读》02 关于java.util.concurrent.atomic包
- 《java.util.concurrent 包源码阅读》05 BlockingQueue