public void setFilter(final Predicate<T> filter, final boolean notifyInsertRemove) {

        this.filter = filter;

        if (!notifyInsertRemove) {
            initializeFromOriginalList();
            return;
        }

        final Set<Integer> oldFilteredIndexes = new HashSet<>(this.itemToOriginalItemMap.values());
        this.itemToOriginalItemMap.clear();

        int origIdx = 0;
        int idx = 0;
        for (T origItem : originalItemList) {
            final boolean isOldFiltered = oldFilteredIndexes.contains(origIdx);
            final boolean isNewFiltered = isFiltered(origItem);
            if (isOldFiltered && !isNewFiltered) {
                itemList.remove(idx);
                if (this.notifyOnEvents) {
                    notifyItemRemoved(idx);
                }
            } else if (!isOldFiltered && isNewFiltered) {
                itemList.add(idx, origItem);
                this.itemToOriginalItemMap.put(idx, origIdx);
                if (this.notifyOnEvents) {
                    notifyItemInserted(idx);
                }
            } else if (isOldFiltered && isNewFiltered) {
                this.itemToOriginalItemMap.put(idx, origIdx);
            }
            if (isNewFiltered) {
                idx++;
            }
            origIdx++;
        }

    }
Sets a new filter.
<br />
If notifyInsertRemove is true, then RecyclerView is notified with a series of insert/remove
events with the goal to preserve existing views as much as possible. However, this will throw
IndexOutOfBoundsExceptions if used LayoutManager has "supportsPredictiveItemAnimations" enabled.
See <a href="https://stackoverflow.com/questions/31759171/recyclerview-and-java-lang-indexoutofboundsexception-inconsistency-detected-in">SO article</a>
main/src/main/java/cgeo/geocaching/ui/recyclerview/ManagedListAdapter.java