您可以爲ResultSet
創建一個包裝,使其成爲Iterable
。從那裏你可以迭代以及創建一個流。當然,你必須定義一個映射函數來獲得結果集中的迭代值。
的ResultSetIterable
可能看起來像這樣
public class ResultSetIterable<T> implements Iterable<T> {
private final ResultSet rs;
private final Function<ResultSet, T> onNext;
public ResultSetIterable(ResultSet rs, Function<ResultSet, T> onNext){
this.rs = rs;
//onNext is the mapper function to get the values from the resultSet
this.onNext = onNext;
}
@Override
public Iterator<T> iterator() {
try {
return new Iterator<T>() {
//the iterator state is initialized by calling next() to
//know whether there are elements to iterate
boolean hasNext = rs.next();
@Override
public boolean hasNext() {
return hasNext;
}
@Override
public T next() {
T result = onNext.apply(rs);
//after each get, we need to update the hasNext info
try {
hasNext = rs.next();
} catch (SQLException e) {
//you should add proper exception handling here
throw new RuntimeException(e);
}
return result;
}
};
} catch (Exception e) {
//you should add proper exception handling here
throw new RuntimeException(e);
}
}
//adding stream support based on an iteratable is easy
public Stream<T> stream() {
return StreamSupport.stream(this.spliterator(), false);
}
}
現在,我們有我們的包裝,你可以流過的結果:如果你想使用一個
ResultSet rs = stmt.executeQuery();
List<String> userIdList = new ResultSetIterable(rs, rs -> rs.getString(1)).stream()
.collect(Collectors.toList())
}
' Stream的工廠方法,因爲「迭代直到next()'返回false」,所以你運氣不好。「Java 8中不能用它們表示邏輯。Java 9中將支持這種方法,但是,checke d'SQLException'阻止您編寫簡潔的lambda表達式。你很可能最終會得到一個自定義的'Spliterator',就像在[這個答案](http://stackoverflow.com/a/32232173/2711488)中一樣,它涵蓋的不僅僅是迭代ResultSet。當你經常使用它時,這對工廠是有用的,但是對於轉換單個循環來說,這將是過度的。 – Holger