NPE пока список фильтров с io.reactivex.Observable

Я столкнулся с проблемой, пока пытаюсь отфильтровать ArrayList из String как Observable,

Все работает нормально, если:

MatrixCursor suggestionsCursor =
        new MatrixCursor(new String[]{BaseColumns._ID, COLUMN_FIELD_NO});

for (int i = 0; i < data.size(); i++) {
    if (data.get(i) != null)
        if (data.get(i).toLowerCase().contains(newText.toLowerCase()))
            filtered.add(data.get(i));
}

int key = 0;
for (String suggestion : filtered) {
    suggestionsCursor.addRow(new Object[]{key++, suggestion});
}

Но не если

MatrixCursor suggestionsCursor =
        new MatrixCursor(new String[]{BaseColumns._ID, COLUMN_FIELD_NO});

Observable.fromIterable(data)
        .filter(it->it!=null && it.toLowerCase().contains(newText.toLowerCase()))
        .subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread())
        .toList()
        .subscribe(strings -> {
            int key = 0;
            for (String suggestion : strings) {
                suggestionsCursor.addRow(new Object[]{key++, suggestion});
            }          
        });

Потому что я получаю ошибку

io.reactivex.exceptions.OnErrorNotImplementedException: итератор возвратил нулевое значение

Где я тут не прав?

3 ответа

Решение

Оба ответа хороши, но я нашел более простое решение.

data.removeAll(Collections.singleton(null));

После заполнения данных Strings

Как уже упоминалось в комментарии, null значения в итерируемой последовательности не поддерживаются. Эта проверка применяется в ObservableFromIterable.java учебный класс:

v = ObjectHelper.requireNonNull(it.next(), "The iterator returned a null value");

Это также означает, что такой фильтр не помогает

.filter(it -> it != null)

В любом случае, хорошее эмпирическое правило будет обрабатывать исключения ошибок

Observable.fromIterable(data)
        .filter(it->it!=null && it.toLowerCase().contains(newText.toLowerCase()))
        .subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread())
        .toList()
        .subscribe(strings -> {
            int key = 0;
            for (String suggestion : strings) {
                suggestionsCursor.addRow(new Object[]{key++, suggestion});
            }          
        }, error -> {
           /* handle exceptions here */
        });

Вы можете использовать библиотеку Iterable Extensions ( IxJava) для предварительной обработки, с которой вы можете работать nulls:

Observable.fromIterable(
        Ix.from(data)
        .filter(it -> it != null 
             && it.toLowerCase().contains(newText.toLowerCase())
        )
    )
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())
    .toList()
    .subscribe(strings -> {
        int key = 0;
        for (String suggestion : strings) {
            suggestionsCursor.addRow(new Object[]{key++, suggestion});
        }          
    }, 
    Throwable::printStackTrace);
Другие вопросы по тегам