我正在尝试在 Kotlin 中构建一个流解决方案
在 Java 中,我能够在“单个”流中完成此操作
// JAVA SOLUTION - WORKS
new BufferedReader(new InputStreamReader(System.in))
.lines()
.map(line -> line.split(","))
.map(Player::fromLine)
.filter(p -> p.games >= 15)
.sorted((p1, p2) -> Double.compare(p2.ppg, p1.ppg))
.limit(10)
.map(Player::reportLine)
.forEach(System.out::println);
在上面的 Java 代码中,我创建了一个
Player
记录,其 fromLine
静态方法执行字符串到数字的转换,并使用在 ppg
字段中计算的每场比赛得分创建玩家记录。
但是,我无法直接将其翻译为 Kotlin。我试过:
// KOTLIN ATTEMPT - THIS DOES NOT WORK
BufferedReader(InputStreamReader(System.`in`))
.lines()
.map { it.split(",") }
.map { Player.fromLine(it) }
.filter { it.games >= 15 }
.sortedByDescending { it.ppg } // ERROR ON THIS LINE
.take(10)
.map { it.reportLine() }
.forEach { println(it) }
错误是(毫不奇怪)
错误:未解析的参考。由于接收器类型不匹配,以下候选者均不适用:...
我认为这是因为
sortedByDescending
希望它的接收器是一个数组或一个可迭代的(我从文档中知道)。我已经解决了这个问题,并通过两步操作让我的代码正常工作:
// KOTLIN SOLUTION - WORKS (but can it done in one shot?)
val players = BufferedReader(InputStreamReader(System.`in`))
.lines()
.map { it.split(",") }
.map { Player.fromLine(it) }
.filter { it.games >= 15 }
.toList()
players.sortedByDescending { it.ppg }
.take(10)
.map { it.reportLine() }
.forEach { println(it) }
有什么方法可以将排序“放入单个流中”吗?
我想一个更深层次的问题可能是,为什么在非工作解决方案中的
filter
调用之前,sortedByDescending
调用的结果没有产生正确的可迭代对象?
我不太确定您是否计划使用 Java stdlib 中的
Stream
或 Kotlin stdlib 中的 Sequence
。您使用的运算符 (take()
、sortedByDescending()
) 是 Kotlin 的典型操作符,但您使用与 Java 中完全相同的 .lines()
函数,因此它返回 Java 的典型 API (Stream
)。
要解决此问题,您需要坚持使用 Java API,因此请像在 Java 代码中一样使用
sorted()
和 limit()
。或者您需要坚持使用 Kotlin API,因此请使用 lineSequence()
而不是 lines()
。