代码之家  ›  专栏  ›  技术社区  ›  Anton A.

使用io.reactivex.observate筛选列表时的NPE

  •  0
  • Anton A.  · 技术社区  · 7 年前

    我在尝试过滤时遇到问题 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 回复  |  直到 7 年前
        1
  •  1
  •   Lino    7 年前

    如评论所述, null 不支持iterable序列中的值。此检查在 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 */
            });
    
        2
  •  1
  •   akarnokd    7 年前

    您可以使用Iterable扩展库( IxJava )对于预处理,我们使用 null 学生:

    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);
    
        3
  •  0
  •   Anton A.    7 年前

    两个答案都很好,但我找到了更简单的解决办法。

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

    填充数据后 Strings