如何在列表中找到特定类型的元素,并智能转换结果?
How can I find an element of a particular type in a list, and also smart cast the result?
假设我有一个List<Animal>
,我想在其中找到第一个Dog
。然后我想访问找到的 Dog
.
的一些 Dog
特定属性
find
确实不行:
val dog = animals.find { it is Dog }
// dog is of type "Animal?", but I want "Dog?"
我可以使用 filterIsInstance
:
val dog = animals.filterIsInstance<Dog>().firstOrNull()
但这遍及整个动物列表。我希望它在找到第一只狗时停止。执行此操作的内置方法是什么?
您可以使用 firstNotNullOfOrNull
(说起来有点啰嗦 :D),用 as?
代替 is
。
val dog = animals.firstNotNullOfOrNull { it as? Dog }
它将转换应用于每个元素,returns 第一个 not-null 转换结果,如果没有这样的结果,则为 null。
还有对应的 firstNotNullOf
会在没有 not-null 结果时抛出异常。
您可以使用序列进行延迟计算
比较以下代码示例:
渴望
val firstString = listOf(1, "2", 3, "4", 5, "6")
// following operations are applied to List
.filterIsInstance<String>()
.onEach { println(it) }
.firstOrNull()
println("Result: $firstString")
输出:
2
4
6
Result: 2
懒惰
val firstString = listOf(1, "2", 3, "4", 5, "6")
.asSequence()
// following operations are applied to Sequence
.filterIsInstance<String>()
.onEach { println(it) }
.firstOrNull()
println("Result: $firstString")
输出:
2
Result: 2
这两种情况的结果是相同的,但对于懒惰的情况,在找到第一个匹配项后不会进行进一步的步骤。
假设我有一个List<Animal>
,我想在其中找到第一个Dog
。然后我想访问找到的 Dog
.
Dog
特定属性
find
确实不行:
val dog = animals.find { it is Dog }
// dog is of type "Animal?", but I want "Dog?"
我可以使用 filterIsInstance
:
val dog = animals.filterIsInstance<Dog>().firstOrNull()
但这遍及整个动物列表。我希望它在找到第一只狗时停止。执行此操作的内置方法是什么?
您可以使用 firstNotNullOfOrNull
(说起来有点啰嗦 :D),用 as?
代替 is
。
val dog = animals.firstNotNullOfOrNull { it as? Dog }
它将转换应用于每个元素,returns 第一个 not-null 转换结果,如果没有这样的结果,则为 null。
还有对应的 firstNotNullOf
会在没有 not-null 结果时抛出异常。
您可以使用序列进行延迟计算
比较以下代码示例:
渴望
val firstString = listOf(1, "2", 3, "4", 5, "6")
// following operations are applied to List
.filterIsInstance<String>()
.onEach { println(it) }
.firstOrNull()
println("Result: $firstString")
输出:
2
4
6
Result: 2
懒惰
val firstString = listOf(1, "2", 3, "4", 5, "6")
.asSequence()
// following operations are applied to Sequence
.filterIsInstance<String>()
.onEach { println(it) }
.firstOrNull()
println("Result: $firstString")
输出:
2
Result: 2
这两种情况的结果是相同的,但对于懒惰的情况,在找到第一个匹配项后不会进行进一步的步骤。