目录结构
debounce
此操作符会过滤掉发射速率过快的数据项。emmm这样来理解:此操作符需要传入一个时间单位,然后在此事件单位内发射的数据都会被过滤掉,不会传递到下游。看例子:
Observable.just(1, 2, 3, 4, 5, 6, 7)
.debounce(1, TimeUnit.SECONDS)
.subscribe(new Observer<Integer>() {
@Override
public void onSubscribe(Disposable d) {
Log.d("debounce", "onSubscribe");
}
@Override
public void onNext(Integer integer) {
Log.d("debounce", "onNext: 接收的数据--> " + integer);
}
@Override
public void onError(Throwable e) {
Log.d("debounce", "onError");
}
@Override
public void onComplete() {
Log.d("debounce", "onComplete");
}
});
/**
* 04-09 14:20:24.866 14445-14445/com.example.testlink D/debounce: onSubscribe
* 04-09 14:20:24.866 14445-14445/com.example.testlink D/debounce: onNext: 接收的数据--> 7
* 04-09 14:20:24.866 14445-14445/com.example.testlink D/debounce: onComplete
*/
}
由最后的结果可以知道,数据源共有7个数据,但最终只接收的了最后一个数据。在一秒的时间内已经发射了前面6个数据,自然下游接收的数据就只有一个了。
distinct
过滤规则:只允许还没有发射过的数据项通过。简单说就是去重。基本数据的例子就不做示范,举个引用类型的数据来看是否也能够达到去重的效果:
User user1 = new User("15");
User user2 = new User("16");
User user3 = new User("17");
List<User> list = new ArrayList<>();
list.add(user1);
list.add(user1);
list.add(user2);
list.add(user2);
list.add(user3);
list.add(user3);
list.add(user3);
Observable.fromIterable(list)
.distinct()
.subscribe(new Observer<User>() {
@Override
public void onSubscribe(Disposable d) {
Log.d("distinct", "onSubscribe: ");
}
@Override
public void onNext(User integer) {
Log.d("distinct", "onNext: " + integer.age);
}
@Override
public void onError(Throwable e) {
Log.d("distinct", "onError: ");
}
@Override
public void onComplete() {
Log.d("distinct", "onComplete: ");
}
});
/**
*04-09 17:16:31.456 25133-25133/com.example.testlink D/distinct:
onSubscribe:
04-09 17:16:31.456 25133-25133/com.example.testlink D/distinct: onNext: 15
04-09 17:16:31.456 25133-25133/com.example.testlink D/distinct: onNext: 16
04-09 17:16:31.456 25133-25133/com.example.testlink D/distinct: onNext: 17
04-09 17:16:31.456 25133-25133/com.example.testlink D/distinct: onComplete:
*/
创建了一个简单的User对象,有一个带一个age参数的构造方法,往list里加入重复对象。结果也只接收了3个不重复的对象。结论就是distinct 也能去重引用型数据。
elementAt
该操作符只选择发射数据序列中指定索引位置的数据来发射。并且只发射一次。索引位置从0开始。
Observable.just(1, 2, 3, 4, 5, 6)
.elementAt(3)
.subscribe(new MaybeObserver<Integer>() {
@Override
public void onSubscribe(Disposable d) {
Log.d("elementAt", "onSubscribe: ");
}
@Override
public void onSuccess(Integer integer) {
Log.d("elementAt", "onSuccess: " + integer);
}
@Override
public void onError(Throwable e) {
Log.d("onError", "onError: ");
}
@Override
public void onComplete() {
Log.d("onComplete", "onComplete: ");
}
});
/**
*04-09 17:57:13.416 23283-23283/? D/elementAt: onSubscribe:
04-09 17:57:13.416 23283-23283/? D/elementAt: onSuccess: 4
*/
elementAt除了传入索引值外,还可以传入一个默认值。当发射序列索引值没有找到当前的索引值时就以默认值为数据发射。而如果不传入默认值时,也不会抛出越界异常,而是直接发射onComplete通知结束。
filter
字面意思很好理解,过滤掉不符合条件的数据。如下只发射大于3的数据出去。
Observable.just(1, 2, 3, 4, 5, 6, 7)
.filter(integer -> integer > 3)
.subscribe(new Observer<Integer>() {
@Override
public void onSubscribe(Disposable d) {
Log.d("filter", "onSubscribe: ");
}
@Override
public void onNext(Integer integer) {
Log.d("filter", "onNext: " + integer);
}
@Override
public void onError(Throwable e) {
Log.d("filter", "onError: ");
}
@Override
public void onComplete() {
Log.d("filter", "onComplete: ");
}
});
/**
* 04-09 14:22:53.576 16809-16809/com.example.testlink D/filter: onSubscribe:
04-09 14:22:53.576 16809-16809/com.example.testlink D/filter: onNext: 4
04-09 14:22:53.576 16809-16809/com.example.testlink D/filter: onNext: 5
04-09 14:22:53.576 16809-16809/com.example.testlink D/filter: onNext: 6
04-09 14:22:53.576 16809-16809/com.example.testlink D/filter: onNext: 7
04-09 14:22:53.576 16809-16809/com.example.testlink D/filter: onComplete:
*/
first
只发射数据里的第一项数据。需要给定一个默认值。内层使用 elementAt 。
@CheckReturnValue @SchedulerSupport(SchedulerSupport.NONE) public final Single<T> first(T defaultItem) { return elementAt(0L, defaultItem); }
ignoreElements
不发射任何数据,只发射Observable的onComplete 通知。这里不做例子。
last
只发射最后一项数据,传入数据序列的索引值,需要给定默认索引值。这里不给出例子。
sample
发射在那段时间内的第一项数据。传入一个时间标记为采样单位,发射每过这个时间内的第一项数据。
Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> e) throws Exception {
e.onNext(1);
Thread.sleep(1000);
e.onNext(2);
Thread.sleep(1000);
e.onNext(3);
Thread.sleep(1000);
e.onNext(4);
Thread.sleep(1000);
e.onNext(5);
Thread.sleep(1000);
e.onNext(6);
}
})
.sample(1000, TimeUnit.MILLISECONDS)
.subscribe(new Observer<Integer>() {
@Override
public void onSubscribe(Disposable d) {
Log.d("sample", "onSubscribe: ");
}
@Override
public void onNext(Integer integer) {
Log.d("sample", "onNext: " + integer);
}
@Override
public void onError(Throwable e) {
Log.d("sample", "onError: ");
}
@Override
public void onComplete() {
Log.d("sample", "onComplete: ");
}
});
这里来预期一下结果。每隔1秒采样一次,共有6个数据,并且刚好是发送完一个数据睡眠一秒。那么按照这个采样结果下游接收的数据应该就是所有的数据了。看结果
04-10 16:55:33.866 26799-26799/com.example.testlink D/sample: onSubscribe:
04-10 16:55:34.876 26799-26828/com.example.testlink D/sample: onNext: 1
04-10 16:55:35.876 26799-26828/com.example.testlink D/sample: onNext: 2
04-10 16:55:36.876 26799-26828/com.example.testlink D/sample: onNext: 3
04-10 16:55:37.876 26799-26828/com.example.testlink D/sample: onNext: 4
04-10 16:55:38.876 26799-26828/com.example.testlink D/sample: onNext: 5
04-10 16:55:39.876 26799-26828/com.example.testlink D/sample: onNext: 6
正如预期一样的。那么将采样时间修改为3秒,那么预期结果应该只出现2个:
04-10 17:01:20.686 31055-31055/com.example.testlink D/sample: onSubscribe:
04-10 17:01:23.686 31055-31089/com.example.testlink D/sample: onNext: 3
04-10 17:01:26.686 31055-31089/com.example.testlink D/sample: onNext: 6
完全如预期一样。
skip or skipLast
skip是跳过前面指定n项数据,最终发射后面的数据,skiplast是从倒序着来,跳过后面指定n项数据,发射前面的数据。另外skip跟skiplast还可以传入一个时间参数。意为只发射在当前单位时间内发射后或前的数据。传入时间单位就这样类似 debounce的效果。
take or takeLast
take 、takeLast 就是跟skip系列相反了。只发射指定n项前或者最后n项的数据。