Отфильтровать ноль в списке полей неизменяемых объектов - PullRequest
0 голосов
/ 02 декабря 2018

У меня есть неизменный объект:

class Foo(
        val name: String,
        val things: List<Thing>
)

Сторонний lib создает объект Foo с некоторыми объектами Thing 'null'.

Я создаю новый объект:

val foo = thirdPartyGetFoo()
val filteredFoo = Foo(foo.name, foo.things.filterNotNull())

Это работает, однако AndroidStudio скрывает вызов функции filterNotNull и выдает предупреждение:

Бесполезный вызов для типа коллекции: Инспекция сообщает о фильтрационных вызовах в уже отфильтрованных коллекциях.

Это правильный способ отфильтровать этот список?Должен ли я игнорировать предупреждение или есть лучший способ?

1 Ответ

0 голосов
/ 02 декабря 2018

Вы не указываете, из какой библиотеки создается объект с нулями.Некоторые библиотеки десериализации могут использовать статические фабричные методы, которые вы можете настроить, и затем фабричный метод обнуляет ноль.Например, если бы это был Джексон, вы бы просто:

class Foo(val name: String, val things: List<Thing>) {
    companion object {
        @JsonCreator 
        @JvmName("createFromNullable")
        fun create(name: String, things: List<Thing?>) = Foo(name, things.filterNotNull())

        fun create(name: String, things: List<Thing>) = Foo(name, things)
    }
}

Затем ...

val goodFoo = jacksonObjectMapper().readValue<Foo>(someJsonWithNulls)

Может быть, в вашей библиотеке есть похожие параметры?

Если нети у вас нет 100 таких вещей с этой проблемой, я, вероятно, создал бы временный класс для хранения результатов и преобразовал бы его в конечный класс:

open class FooNullable(val name: String, open val things: List<Thing?>) {
    open fun withoutNulls(): Foo = Foo(name, things.filterNotNull())
}

class Foo(name: String, override val things: List<Thing>) : FooNullable(name, things) {
    override fun withoutNulls(): Foo = this
}

Затем вы можете десериализовать в FooNullable и просто позвоните withoutNulls(), чтобы получить другой чистый аромат.И если вы случайно вызываете его на один без нуля, он просто ничего не делает.

val goodFoo = Foo("", emptyList<Thing>())
val alsoGoodFoo = goodFoo.withoutNulls()        // NOOP does nothing

val badFoo = thirdPartyGetFoo()
val betterFoo = badFoo.withoutNulls()           // clean up the instance

val safeFoo = thirdPartyGetFoo().withoutNulls() // all at once!

Не самый чистый, но работает.Недостатки - это второй шаг, хотя, похоже, вы все равно планировали это сделать.Но эта модель безопаснее, чем то, что вы предложили, поскольку вы ЗНАЕТЕ, какой тип объекта у вас есть, и, следовательно, вы продолжаете быть безопасным с точки зрения типов и имеете компилятор, помогающий избежать ошибки.

Вам не нужно использовать наследование, как в приведенном выше примере, я просто пытался унифицировать API на случай, если была причина иметь любую версию в руках и знать, какая есть, а также действовать в соответствии сих аналогичным образом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...