2017-03-16 63 views
1

我有下面的代碼片段Java流遍歷ResultSet對象

ResultSet rs = stmt.executeQuery(); 
List<String> userIdList = new ArrayList<String>(); 
while(rs.next()){ 
    userIdList.add(rs.getString(1)); 
} 

我可以使用Java流/ Lambda表達式來執行本次迭代,而不是一個while循環來填充列表?

+2

' Stream的工廠方法,因爲「迭代直到next()'返回false」,所以你運氣不好。「Java 8中不能用它們表示邏輯。Java 9中將支持這種方法,但是,checke d'SQLException'阻止您編寫簡潔的lambda表達式。你很可能最終會得到一個自定義的'Spliterator',就像在[這個答案](http://stackoverflow.com/a/32232173/2711488)中一樣,它涵蓋的不僅僅是迭代ResultSet。當你經常使用它時,這對工廠是有用的,但是對於轉換單個循環來說,這將是過度的。 – Holger

回答

2

您可以爲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()) 

}

+0

或者你可以使用'org.apache.commons.dbutils.ResultSetIterator.iterable(rowSet)' –