Anton A.
Anton A.

Reputation: 1748

NPE while filter list with io.reactivex.Observable

I facing with problem while try to filter ArrayList of String as Observable.

All works fine if:

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});
}

But not if

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});
            }          
        });

Because I get an error

io.reactivex.exceptions.OnErrorNotImplementedException: The iterator returned a null value

Where am I wrong here?

Upvotes: 1

Views: 325

Answers (3)

Anton A.
Anton A.

Reputation: 1748

Both answears are good, but I found easier solution.

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

After populate data with Strings

Upvotes: 0

akarnokd
akarnokd

Reputation: 69997

You could use the Iterable Extensions library (IxJava) for preprocessing, which let's you work with 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);

Upvotes: 1

Lino
Lino

Reputation: 6160

As mentioned in the comment, null values in the iterable sequence are not supported. This check is enforced in the ObservableFromIterable.java class:

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

This also means that a filter like this does not help

.filter(it -> it != null)

In any case, a good rule of thumb will be to handle error exceptions

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 */
        });

Upvotes: 1

Related Questions