Java 8 "Необязательно" плохая практика? - PullRequest
0 голосов
/ 17 мая 2018

У меня есть код:

val d = Single
            .zip<List<X>, Optional<Y>, DataContent>(
                    xSingle,
                    YSingle,
                    BiFunction { x, y ->
                        val b = if (y.isPresent()) {
                            y.get()
                        } else {
                            null
                        }
                        return@BiFunction DataContent(x, b)
                    })
            .subscribe({ data ->
                ...
            }, { t ->
                ...
            })

Я слышал, что использование Optional для проверки нулевого значения, как показано в примере, является плохой практикой. Это правда? Зачем? Может кто-нибудь показать альтернативу, используя RxJava2?

1 Ответ

0 голосов
/ 20 мая 2018

Как правило, Optional имеет ограниченный набор вариантов использования и может быть перегружен.Вы можете сослаться на этот ответ автора Java Брайана Гетца, чтобы понять это (выделение добавлено):

Но у нас было четкое намерение при добавлении этого [java.util.Optional], и это не должно было быть общим назначением типа «Может быть» или «Некоторые», так как многие люди хотели бы, чтобы мы это делали.Мы намеревались предоставить ограниченный механизм для возвращаемых типов библиотечных методов, где должен быть четкий способ представления «без результата», и использование нулевого для такого значения в подавляющем большинстве случаев могло вызвать ошибки.

Например, вывероятно, никогда не следует использовать его для чего-то, что возвращает массив результатов или список результатов;вместо этого верните пустой массив или список. Вы почти никогда не должны использовать его в качестве поля чего-либо или параметра метода.

В опубликованном исходном примере Optional<Y> используется как параметр метода, так что это противЛучшие практики Java.Кроме того, Maybe идиоматичен в RxJava.

Предполагается, что у вас есть что-то вроде следующего:

class X
class Y
data class DataContent constructor(val listOfX: List<X>, val y: Y)

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

fun zipToDataContent(maybeListOfX: Maybe<List<X>>, maybeY: Maybe<Y>): Maybe<DataContent> =
        Maybe.zip<List<X>, Y, DataContent>(
                maybeListOfX,
                maybeY,
                BiFunction { listOfX, y -> DataContent(listOfX, y) })

Тесты:

@Test
fun testZipToDataContentWithRealY() {
    val x = X()
    val y = Y()

    val maybeListOfX = Maybe.just(listOf(x))
    val maybeY = Maybe.just(y)

    zipToDataContent(maybeListOfX, maybeY).test()
            .assertOf {
                Maybe.just(DataContent(listOf(x), y))
            }
}

@Test
fun testZipToDataContentWithEmptyY() {
    val x = X()

    val maybeListOfX = Maybe.just(listOf(x))
    val maybeY = Maybe.empty<Y>()

    zipToDataContent(maybeListOfX, maybeY).test()
            .assertOf {
                Maybe.empty<DataContent>()
            }
}
...