【问题标题】:Producing a List from a ResultSet从 ResultSet 生成列表
【发布时间】:2017-06-01 19:50:39
【问题描述】:

我不完全确定这是可能的,我绝对不知道要搜索什么或如何简明地解释它,但这似乎是一个 kotlin-y 的事情,如果它是我不会感到惊讶可能。

我想用listOf() 实例化一个列表,但不是为列表提供元素,而是提供一些生成列表元素的代码。

例如,使用 ResultSet:(这不是有效代码)

val list: List<Int> = listOf(
    while(resultSet.next()){
        return resultSet.getInt(1)
    }
)

这样的事情可能吗?

【问题讨论】:

  • 如果您想要将ResultSet 映射到IterableList 的通用解决方案,有多种方法可以在其上定义扩展函数。否则,由于ResultSet 没有扩展这些在 Kotlin 中易于使用的接口,如果您只需要这样做一次,那么只需迭代集合并将每个元素添加到可变列表的简单解决方案可能就是最好的一个。
  • @zsmb13 是的,我添加了一个扩展函数并按照您在这种情况下的建议实现了它,但我的问题更多是出于这个特定用例的好奇,而不是专门针对 ResultSets

标签: kotlin jdbc sequence resultset


【解决方案1】:

ResultSet 没有进行此类转换的最佳界面。但它看起来像:

val list = resultSet.use {
    generateSequence {
        if (resultSet.next()) resultSet.getInt(1) else null
    }.toList()  // must be inside the use() block
} 

// resultSet is already closed automatically at this point

另请参阅:generateSequence()


如果您想将其保留为 Sequence 而不是 List 以进行延迟处理,则不能使用 .use() 自动关闭助手。

val seq = generateSequence {
    if (resultSet.next()) resultSet.getInt(1) else null
}

// later remember to call resultSet.close(), since the resultSet is still open

使用 Kotlin 1.1 实验性 coroutines,您可以:

val seq = buildSequence {
    while (resultSet.next()) {
        yield(resultSet.getInt(1))
    }

    // resultSet.close() might work ok here
}

// if not, later remember to resultSet.close()

另请参阅:buildSequence()

【讨论】:

  • 这些非常好用,非常感谢!如果在 OSGi 环境中使用,请稍加说明 - .use {} 需要 kotlin-stdlib-jdk7 不符合 OSGi 标准,因此很不幸,似乎有必要手动关闭 resultSet
  • 生成这样的序列更容易generateSequence { resultSet.takeIf { it.next() } }
【解决方案2】:

我突然想到你也可以使用generateSequence。支持杰森更快地完成它^^

这是我想出的(未经测试,但相当短):

val list = generateSequence {
    if(!resultSet.next()) null
    else resultSet.getInt(1)
}.toList()

【讨论】:

    【解决方案3】:

    从 kotlin 1.3 开始

    sequence {
        while (rs.next()) {
            yield(rs.getString(1))
        }
    }.toList(
    

    【讨论】:

      【解决方案4】:

      通过分解出值“extraction”,可以使序列方法更通用:

      fun <T> ResultSet.asSequence( extract: () -> T ) : Sequence<T> = generateSequence {
              if (this.next()) extract() else null
          }
      
      

      然后像这样使用它:

      resultSet.asSequence { resultSet.getString(1) }
      

      【讨论】:

        猜你喜欢
        • 2017-03-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-01-20
        • 1970-01-01
        • 2022-01-03
        相关资源
        最近更新 更多