You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Kotlin中filterNotNull处理对象属性的编译问题咨询

Handling Nullable Properties in Kotlin Collections

Great question—this is a common point of confusion with Kotlin's smart casts and collection operations! Let's unpack why the compiler behaves this way and what clean alternatives you can use.

Why the Compiler Doesn't Recognize it.venue as Non-Null After Filtering

When you use events.filterNotNull(), you're filtering out null elements from the list itself. Kotlin's compiler can track that every element in the resulting list is non-null, so accessing .name (a non-null property of the non-null element) is safe.

But when you do events.filter { it.venue != null }, you're filtering based on a nullable property of the list elements, not the elements themselves. Kotlin's smart cast can't carry that property-level non-null guarantee across the filtermap boundary. The compiler still sees it.venue as Venue? in the map block because it can't verify that no other code modified the property between the filter and map operations (even if you know it didn't).

Clean Alternatives for Nullable Properties

Luckily, there are several idiomatic ways to handle this without relying on risky !! assertions:

  1. Use mapNotNull to extract non-null properties first
    This is the most concise and safe approach. mapNotNull will skip any elements where the lambda returns null, and the resulting list will only contain non-null values:

    data class Event(val venue: Venue?)
    data class Venue(val name: String)
    
    val events: List<Event> = // your list of events
    val venueNames: List<String> = events.mapNotNull { it.venue?.name }
    

    Or if you need to work with the Venue object before getting the name:

    val venueNames = events.mapNotNull { it.venue }.map { it.name }
    
  2. Filter first, then use safe calls with let
    If you need to keep the filtered list of Event objects for other operations, you can combine filtering with let to safely access the non-null property:

    val filteredEvents = events.filter { it.venue != null }
    val venueNames = filteredEvents.map { it.venue?.let { venue -> venue.name } }
    

    Note this will give you a List<String?>, so you'd still need to use filterNotNull() if you want only non-null names.

  3. Non-null assertion (use with extreme caution)
    If you're 100% certain that every Event in the filtered list has a non-null venue, you can use !!—but this will throw a NullPointerException if your assumption is wrong:

    val venueNames = events.filter { it.venue != null }.map { it.venue!!.name }
    

Key Takeaway

There's no direct equivalent to filterNotNull() for nullable properties, but mapNotNull() is the idiomatic Kotlin solution to safely collect non-null property values from a list. It keeps your code concise and avoids the risk of null pointer exceptions.

内容的提问来源于stack exchange,提问作者hughjdavey

火山引擎 最新活动