code: public <T> Observable<T> observe(@NonNull final String key,
        @NonNull final TypeToken<T> typeTokenOfT, final T defaultValue) {
      Preconditions.checkNotNull(key, KEY_IS_NULL);
      Preconditions.checkNotNull(typeTokenOfT, TYPE_TOKEN_OF_T_IS_NULL);
  
      return observePreferences().filter(new Predicate<String>() {
        @Override public boolean test(@io.reactivex.annotations.NonNull String filteredKey)
            throws Exception {
          return key.equals(filteredKey);
        }
      }).map(new Function<String, T>() {
        @Override public T apply(@io.reactivex.annotations.NonNull String s) throws Exception {
          return get(key, typeTokenOfT, defaultValue);
        }
      });
    }
docs: Gets value from SharedPreferences with a given key and type token
  as a RxJava Observable, which can be subscribed.
  If value is not found, we can return defaultValue.
  
  @param key key of the preference
  @param typeTokenOfT type token of T (e.g. {@code new TypeToken<List<String>> {})
  @param defaultValue default value of the preference (e.g. "" or "undefined")
  @param <T> return type of the preference (e.g. String)
  @return Observable value from SharedPreferences associated with given key or default value