gpt4 book ai didi

java - 让代码更加函数式风格

转载 作者:太空宇宙 更新时间:2023-11-04 06:37:41 27 4
gpt4 key购买 nike

这是 Java-Scala 代码:

class MyDbManager extends SQLiteOpenHelper ....
val cursor = new MyDbManager().getReadableDatabase.query(....)
val result = new ArrayList[MyItem] //???

//?????????
if (cursor.moveToFirst()) {
do {
result + parse(cursor)
} while (cursor.moveToNext())
}
//?????????

cursor.close()
result

我想要做的是不能将任何可变集合和不可变集合与可变变量一起使用。我想做这样的事情:

val result = if (cursor.moveToFirst()) {
do { parse(cursor) } while (cursor.moveToNext())
}

你明白了:不使用任何冗余变量,尤其是可变变量。当然,上面的代码无法编译。

如果可能的话我该如何做到这一点?我希望涉及任何第三方库,尽可能简单。

更新:建议使用“为了”。因为在我的例子中“for”翻译为“map”和“filter”,我想知道为什么这不起作用:

if.(cursor.moveToFirst()) cursor.filter(_.moveToNext()).map { x => parse(x) }

最佳答案

此代码基于 java.sql.ResultSet,但该模式也应该适用于您的情况。

选项 1:提供 foreach 方法

您可以像这样定义一个类:

class Cursor[T](rs: ResultSet)(f: Row => T) {
def foreach(g: T => Unit) {
val row = new Row(rs)
while (rs.next()) {
g(f(row))
}
}
}

它有两个参数:

  • 基础结果集
  • 函数f,为每一行生成一个实例。因此在迭代过程中,会构造基于当前行的实例。

Cursor 类提供了 foreach 方法。因此它可以用于“理解”:

val cursor = Cursor(rs) {
row =>
Person(row.getString(1), row.getString(2))
}

for {
person <- cursor
} {
println(person)
}
<小时/>

为了能够对函数 f 使用 { ... } 语法,需要一个伴随对象:

object Cursor {
def apply[T](rs: ResultSet)(f: Row => T) = {
new Cursor(rs)(f)
}
}

使用代表结果集一行的包装类Row,因为基础结果集的某些方法不应该对函数可见(例如next())。

class Row(rs: ResultSet) {
def getString(n: Int) = rs.getString(n)
def getInt(n: Int) = rs.getInt(n)
// ... more getters for other types
}

选项 2:扩展迭代器

class CursorWithIterator[T](rs: ResultSet)(f: Row => T) extends Iterator[T] {
private val row = new Row(rs)

override def hasNext = rs.next()

override def next() = f(row)
}

您也可以在“理解”中使用迭代器。它使您可以访问完整的集合 API,例如 map 等。

关于java - 让代码更加函数式风格,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25135606/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com