take操作符:只发射前面的N项数据,然后发射完成通知,忽略剩余的数据。
take(int a)只发射前面的a项数据
Observable.just(1, 2, 3, 4, 5, 6, 7, 8, 9).take(3).subscribe(new Consumer() {
@Override
public void accept(Integer integer) {
Log.d("TakeActivity", "integer.intValue():" + integer.intValue());
}
});
输出:
2019-11-28 11:00:26.412 3340-3340/com.jimmy.rx D/TakeActivity: integer.intValue():1
2019-11-28 11:00:26.412 3340-3340/com.jimmy.rx D/TakeActivity: integer.intValue():2
2019-11-28 11:00:26.413 3340-3340/com.jimmy.rx D/TakeActivity: integer.intValue():3
测试:当数据源小于限制数量,则发送全部数据源
Observable.just(1, 2, 3).take(4).subscribe(new Consumer() {
@Override
public void accept(Integer integer) {
Log.d("TakeActivity", "integer" + integer.intValue());
}
});
输出:
2019-11-28 11:00:26.413 3340-3340/com.jimmy.rx D/TakeActivity: integer1
2019-11-28 11:00:26.413 3340-3340/com.jimmy.rx D/TakeActivity: integer2
2019-11-28 11:00:26.413 3340-3340/com.jimmy.rx D/TakeActivity: integer3
测试:当数据源为空的时候不会触发回调
Observable.empty().take(4).subscribe(new Consumer() {
@Override
public void accept(Object o) throws Exception {
LogUtils.d("数据源为空" + o.toString());
}
}, new Consumer() {
@Override
public void accept(Throwable throwable) throws Exception {
LogUtils.d("数据源为空" + throwable.getMessage());
}
});
无输出
测试:take(long,TimeUnit)) 或者 take(long,TimeUnit,Scheduler)),返回规定时间内的数据,其他的忽略
take默认不在任何调度器上使用,该方法可以指定调度器
Observable.interval(1, TimeUnit.SECONDS).take(5, TimeUnit.SECONDS).subscribe(new Consumer() {
@Override
public void accept(Long aLong) throws Exception {
Log.d("TakeActivity", "时间内接收到的数据:" + aLong);
}
});
输出:
2019-11-28 11:22:18.758 8814-8864/com.jimmy.rx D/TakeActivity: 时间内接收到的数据:0
2019-11-28 11:22:19.758 8814-8864/com.jimmy.rx D/TakeActivity: 时间内接收到的数据:1
2019-11-28 11:22:20.758 8814-8864/com.jimmy.rx D/TakeActivity: 时间内接收到的数据:2
2019-11-28 11:22:21.759 8814-8864/com.jimmy.rx D/TakeActivity: 时间内接收到的数据:3
takeLast操作符:发射Observable发射的最后N项数据,忽略前面的数据。
接受一个int a参数,返回数据源最后a个数据
Observable.just(1, 2, 3, 4, 5, 6, 7, 8, 9).takeLast(3).subscribe(new Consumer() {
@Override
public void accept(Integer integer) {
Log.d("TakeActivity", "返回最后几个数值:" + integer.intValue());
}
});
输出:
2019-11-28 11:26:22.181 9054-9054/com.jimmy.rx D/TakeActivity: 返回最后几个数值:7
2019-11-28 11:26:22.181 9054-9054/com.jimmy.rx D/TakeActivity: 返回最后几个数值:8
2019-11-28 11:26:22.181 9054-9054/com.jimmy.rx D/TakeActivity: 返回最后几个数值:9
接受一个时间段n,返回数据源最后时间段n内的数据
Observable.create(new ObservableOnSubscribe() {
@Override
public void subscribe(ObservableEmitter emitter) throws Exception {
for (int i = 0; i <= 5; i++) {
emitter.onNext(i + "");
Thread.sleep(1000);
}
emitter.onComplete();
}
}).subscribeOn(Schedulers.io()).takeLast(2, TimeUnit.SECONDS).subscribe(new Consumer() {
@Override
public void accept(String s) throws Exception {
Log.d("TakeActivity", "返回最后时间段发送的数据" + s);
}
}, new Consumer() {
@Override
public void accept(Throwable throwable) throws Exception {
Log.d("TakeActivity", "返回最后时间段发送的数据" + throwable.getMessage());
}
});
输出:(这里延迟了5秒之后。将最后时间段的数据按顺序一次性全部返回)
2019-11-28 11:40:33.959 9783-9849/com.jimmy.rx D/TakeActivity: 返回最后时间段发送的数据4
2019-11-28 11:40:33.959 9783-9849/com.jimmy.rx D/TakeActivity: 返回最后时间段发送的数据5
StartWith操作符,在发射数据的首部增加数据
增加一个数据
Observable.just(1, 2).startWith(0).subscribe(new Consumer() {
@Override
public void accept(Integer integer) {
Log.d("TakeActivity", "首部增加:" + integer.intValue());
}
});
输出:
2019-11-28 14:00:44.476 12036-12036/com.jimmy.rx D/TakeActivity: 首部增加:0
2019-11-28 14:00:44.476 12036-12036/com.jimmy.rx D/TakeActivity: 首部增加:1
2019-11-28 14:00:44.476 12036-12036/com.jimmy.rx D/TakeActivity: 首部增加:2
增加一组数据
List arrayDeque = Arrays.asList(3, 4);
Observable.just(1, 2).startWith(arrayDeque).subscribe(new Consumer() {
@Override
public void accept(Object o) throws Exception {
Log.d("TakeActivity", "首部增加list:" + o.toString());
}
});
输出:
2019-11-28 14:00:44.476 12036-12036/com.jimmy.rx D/TakeActivity: 首部增加list:3
2019-11-28 14:00:44.476 12036-12036/com.jimmy.rx D/TakeActivity: 首部增加list:4
2019-11-28 14:00:44.476 12036-12036/com.jimmy.rx D/TakeActivity: 首部增加list:1
2019-11-28 14:00:44.476 12036-12036/com.jimmy.rx D/TakeActivity: 首部增加list:2
首部插入一个observable
Observable ob = Observable.just(1, 2);
Observable.just(3, 4).startWith(ob).subscribe(new Consumer() {
@Override
public void accept(Integer integer) throws Exception {
Log.d("TakeActivity", "首部增加Observable:" + integer.toString());
}
});
输出:
2019-11-28 14:06:36.641 12473-12473/com.jimmy.rx D/TakeActivity: 首部增加Observable:1
2019-11-28 14:06:36.641 12473-12473/com.jimmy.rx D/TakeActivity: 首部增加Observable:2
2019-11-28 14:06:36.641 12473-12473/com.jimmy.rx D/TakeActivity: 首部增加Observable:3
2019-11-28 14:06:36.641 12473-12473/com.jimmy.rx D/TakeActivity: 首部增加Observable:4
/*首部插入一系列数据*/
List arrayDeque1 = Arrays.asList(3, 4);
Observable.fromIterable(arrayDeque1).startWithArray(1, 2).subscribe(new Consumer() {
@Override
public void accept(Integer integer) throws Exception {
Log.d("TakeActivity", "首部插入Array:" + integer.toString());
}
});
输出:
2019-11-28 14:09:07.241 12656-12656/com.jimmy.rx D/TakeActivity: 首部插入Array:1
2019-11-28 14:09:07.241 12656-12656/com.jimmy.rx D/TakeActivity: 首部插入Array:2
2019-11-28 14:09:07.241 12656-12656/com.jimmy.rx D/TakeActivity: 首部插入Array:3
2019-11-28 14:09:07.241 12656-12656/com.jimmy.rx D/TakeActivity: 首部插入Array:4
filter操作符只发射通过了谓词测试的数据项
添加一个拦截器,自已断言拦截规则
Observable.just(1, 2, 3, 4, 5).filter(new Predicate() {
@Override
public boolean test(Integer integer) {
if (integer % 2 == 0) {
return true;//true的时候才会执行onnext
} else
return false;//false的时候数据被忽略
}
}).subscribe(new Consumer() {
@Override
public void accept(Integer integer) {
Log.d("TakeActivity", "filter过滤能对2取余的数据:" + integer);
}
});
输出:
2019-11-28 14:16:09.091 13017-13017/com.jimmy.rx D/TakeActivity: filter过滤能对2取余的数据:2
2019-11-28 14:16:09.091 13017-13017/com.jimmy.rx D/TakeActivity: filter过滤能对2取余的数据:4
ofType操作符 是 filter 操作符的一个特殊形式。它过滤一个Observable只返回指定类型的数据。
筛选String类型的数据
Observable.just("字符串类型", 1, 2, 3, 10.0f).ofType(String.class).subscribe(new Consumer() {
@Override
public void accept(String s) throws Exception {
Log.d("TakeActivity", "ofType筛选的规定的类型数据-->" + s);
}
});
输出:
2019-11-28 14:21:31.826 13868-13868/com.jimmy.rx D/TakeActivity: ofType筛选的规定的类型数据-->字符串类型
first操作符,只发射第一项(或者满足某个条件的第一项)数据,部分功能等同于take(1)
取第一个,并且设一个默认值,rxjava2好像是不支持这种形式first(),代替的是firstElement()
Observable.just(0, 1, 2, 3, 4).first(-1)//-1为如果发射的数据未空的时候,设置的默认值
.subscribe(new Consumer() {
@Override
public void accept(Integer integer) throws Exception {
Log.d("TakeActivity", "first操作符---" + integer);
}
}, new Consumer() {
@Override
public void accept(Throwable throwable) throws Exception {
Log.d("TakeActivity", "first操作符---" + throwable.getMessage());
}
});
输出:
2019-11-28 14:35:42.395 14577-14577/com.jimmy.rx D/TakeActivity: first操作符---0
当数据源是空值的时候
Observable.empty().first("1").subscribe(new Consumer() {
@Override
public void accept(Object s) throws Exception {
Log.d("TakeActivity", "first操作符-用了默认值--" + s.toString());
}
});
输出
2019-11-28 14:47:34.311 15463-15463/com.jimmy.rx D/TakeActivity: first操作符-用了默认值--1
firstElement()取第一个数据,无默认值。 内部调用elementAt(0)方法,该方法等同take(1)
Observable.just(0, 1, 2, 3, 4).firstElement().subscribe(new Consumer() {
@Override
public void accept(Integer integer) throws Exception {
Log.d("TakeActivity", "firstElement:" + integer);
}
});
输出
2019-11-28 14:57:05.699 16389-16389/com.jimmy.rx D/TakeActivity: firstElement:0
当发射数据为空的时候,不回调,accept()没有调用
//构造空数据的被观察者
Observable.create(new ObservableOnSubscribe() {
@Override
public void subscribe(ObservableEmitter emitter) throws Exception {
emitter.onComplete();
}
}).firstElement().subscribe(new Consumer() {
@Override
public void accept(Object o) throws Exception {
Log.d("TakeActivity", "firstElement+empty:" + o);
}
});
//发射空数据
Observable.empty().firstElement().subscribe(new Consumer() {
@Override
public void accept(Object o) {
Log.d("TakeActivity", "firstElement+empty:" + o);
}
}, new Consumer() {
@Override
public void accept(Throwable throwable) {
Log.d("TakeActivity", "firstElement+empty:" + throwable.getMessage());
}
});
last操作符,只发射最后一项(或者满足某个条件的最后一项)数据,等同于takelast(1)
无默认值,取最后一个数据
/*lastElement*/
Observable.just(1, 2, 3).lastElement().subscribe(new Consumer() {
@Override
public void accept(Integer integer) throws Exception {
Log.d("TakeActivity", "lastElement--" + integer);
}
});
输出
2019-11-28 15:48:11.722 18400-18400/com.jimmy.rx D/TakeActivity: lastElement--3
last添加有默认值
Observable.just(1, 2, 3).last(1).subscribe(new Consumer() {
@Override
public void accept(Integer integer) throws Exception {
Log.d("TakeActivity", "last--" + integer);
}
});
输出
2019-11-28 15:52:59.751 19343-19343/com.jimmy.rx D/TakeActivity: last--3
single操作符,只发射第一个数据。(数据发射终止之前,有且只能有一个数据,不然会报异常)
错误案例,当终止之前发送了三个数据,这里使用了single取第一个,报错
Observable.just(0, 2, 3).single(1).subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread()).subscribe(new Consumer() {
@Override
public void accept(Integer integer) throws Exception {
LogUtils.d("single操作符---" + integer.toString());
}
}, new Consumer() {
@Override
public void accept(Throwable throwable) throws Exception {
LogUtils.d("single操作符---" + throwable.toString());
}
});
输出异常
java.lang.IllegalArgumentException: Sequence contains more than one element!
正确的single使用方法
Observable.just(0).single(1).subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread()).subscribe(new Consumer() {
@Override
public void accept(Integer integer) throws Exception {
Log.d("TakeActivity", "single操作符---" + integer.toString());
}
});
输出
2019-11-28 16:11:31.714 20027-20027/com.jimmy.rx D/TakeActivity: single操作符---0
当发射数据为空的时候,使用默认值
Observable.empty().single(1).subscribe(new Consumer() {
@Override
public void accept(Object o) throws Exception {
LogUtils.d("single操作符--数据为空-" + o.toString());
/* │ single操作符--数据为空-1*/
}
});
输出
2019-11-28 16:11:31.714 20027-20027/com.jimmy.rx D/TakeActivity: single操作符---1
ignoreElements操作符,不发射任何数据,只发射Observable的终止通知
如果你不关心一个Observable发射的数据,但是希望在它完成时或遇到错误终止时收到通 知,你可以对Observable使用 ignoreElements 操作符,它会确保永远不会调用观察者的 onNext() 方法。
//ignoreElements 忽略所有,直接跳到完成,使用Action回调函数
Observable.just(1, 2, 3)
.ignoreElements()
.subscribe(new Action() {
@Override
public void run() throws Exception {
LogUtils.d("ignoreElements结束");
}
});
输出
ignoreElements结束
skip操作符抑制Observable发射的前N项数据,通俗的说就是跳过前面的N项数据
跳过前面的一项
Observable.just(1, 2, 3).skip(1).subscribe(new Consumer() {
@Override
public void accept(Integer integer) throws Exception {
Log.d("TakeActivity", "skip:" + integer);
}
});
输出
2019-11-28 16:24:33.839 20688-20688/com.jimmy.rx D/TakeActivity: skip:2
2019-11-28 16:24:33.839 20688-20688/com.jimmy.rx D/TakeActivity: skip:3
skip(long,TimeUnit)),跳过前面时间内的数据
skip(long,TimeUnit,Scheduler)),跳过前面时间的数据,并且设定调度器
SkipLast(int a) ,跳过最后的几个数据
Observable.just(1, 2, 3).skipLast(1).subscribe(new Consumer() {
@Override
public void accept(Integer integer) throws Exception {
Log.d("TakeActivity", "skip:" + integer);
}
});
输出
2019-11-28 16:29:28.401 20938-20938/com.jimmy.rx D/TakeActivity: skip:1
2019-11-28 16:29:28.401 20938-20938/com.jimmy.rx D/TakeActivity: skip:2
SkipLast(long,TimeUnit)),跳过最后时间内的数据
SkipLast(long,TimeUnit,Scheduler)),跳过最后时间的数据,并且设定调度器
Distinct操作符,抑制(过滤掉)重复的数据项
过滤重复项(目标是全部数据)
List arrayDeque2 = Arrays.asList(3, 4, 2, 3);
Observable.fromIterable(arrayDeque2).distinct().subscribe(new Consumer() {
@Override
public void accept(Object o) throws Exception {
Log.d("TakeActivity", o.toString());
}
});
输出:
2019-11-28 17:07:54.820 21646-21646/com.jimmy.rx D/TakeActivity: 3
2019-11-28 17:07:54.820 21646-21646/com.jimmy.rx D/TakeActivity: 4
2019-11-28 17:07:54.820 21646-21646/com.jimmy.rx D/TakeActivity: 2
distinct(Func1)接受操作符有一个变体接受一个函数。这个函数根据原始Observable发射的数据项产生一个 Key,然后,比较这些Key而不是数据本身,来判定两个数据是否是不同的。
Observable.just(1, 2, 2, 3, 4, 4, 5).distinct(new Function() {
@Override
public Object apply(Integer integer) throws Exception {
return 3 > integer ? "tag1" : "tag2";
//这里返回的integer是原来的所有数据,1,2,3,4,4,5
//如果3>integer,那么这个值key就是tag1,如果3() {
@Override
public void accept(Integer integer) throws Exception {
Log.d("TakeActivity", "distinct+integer:" + integer);
}
});
输出
2019-11-28 17:51:24.563 32733-32733/com.jimmy.rx D/TakeActivity: distinct+integer:1
2019-11-28 17:51:24.563 32733-32733/com.jimmy.rx D/TakeActivity: distinct+integer:3
distinctUntilChanged操作符,控制相邻的发射数据不能是相同的。
Observable.just(1, 2, 2, 3, 4, 3, 5).distinctUntilChanged().subscribe(new Consumer() {
@Override
public void accept(Integer integer) throws Exception {
Log.d("TakeActivity", "integer:" + integer);
}
});
输出:
2019-11-28 18:02:25.854 2467-2467/com.jimmy.rx D/TakeActivity: integer:1
2019-11-28 18:02:25.855 2467-2467/com.jimmy.rx D/TakeActivity: integer:2
2019-11-28 18:02:25.855 2467-2467/com.jimmy.rx D/TakeActivity: integer:3
2019-11-28 18:02:25.855 2467-2467/com.jimmy.rx D/TakeActivity: integer:4
2019-11-28 18:02:25.855 2467-2467/com.jimmy.rx D/TakeActivity: integer:3
2019-11-28 18:02:25.855 2467-2467/com.jimmy.rx D/TakeActivity: integer:5
ElementAt操作符 只发射第N项数据
elementAt(int a))发射第a项的数据
Observable.just(1, 2, 2, 3, 4, 3, 5).elementAt(2).subscribe(new Consumer() {
@Override
public void accept(Integer integer) throws Exception {
Log.d("TakeActivity", "elementAt:" + integer);
}
});
输出
2019-11-28 18:08:55.769 3451-3451/com.jimmy.rx D/TakeActivity: elementAt:2
elementAt(int a, int defaultb)第a项的数据,如果a项没有的话,那么使用defaultb数据
Observable.just(1, 2, 2, 3, 4, 3, 5).elementAt(10, 999).subscribe(new Consumer() {
@Override
public void accept(Integer integer) throws Exception {
Log.d("TakeActivity", "elementAt:" + integer);
}
});
输出
2019-11-28 18:21:51.783 3958-3958/com.jimmy.rx D/TakeActivity: elementAt:999
elementAtOrError(int a),第a项如果没有数据的话,抛出异常到accept(Throwable throwable)
Observable.just(1, 2, 2, 3, 4, 3, 5).elementAtOrError(10).subscribe(new Consumer() {
@Override
public void accept(Integer integer) throws Exception {
Log.d("TakeActivity", "elementAt:" + integer);
}
}, new Consumer() {
@Override
public void accept(Throwable throwable) {
Log.d("TakeActivity", "elementAtOrError" + throwable.getMessage());
}
});
输出:这里异常捕获为null
sample操作符,定期发射Observable最近发射的数据项。类似于 ThrottleLast
注意:如果自上次采样以来,原始Observable没有发射任何数据,这个操作返回的 Observable在那段时间内也不会发射任何数据。
Observable.create(new ObservableOnSubscribe() {
@Override
public void subscribe(ObservableEmitter emitter) throws Exception {
for (int i = 0; i <= 30; i++) {//模拟延时发送
emitter.onNext(i + "");
Thread.sleep(1000);
}
emitter.onComplete();//发送完成必须调用complete
}
}).subscribeOn(Schedulers.io()).sample(5, TimeUnit.SECONDS).subscribe(new Consumer() {
@Override
public void accept(String s) throws Exception {
Log.d("TakeActivity", "sample+" + s);
}
}, new Consumer() {
@Override
public void accept(Throwable throwable) throws Exception {
Log.d("TakeActivity", "sample+" + throwable.getMessage());
}
});
发送的数据是0-30. 时间是31秒。
从输出数据上看, 数据30没有被发送,这里有疑问。 但是测试只发送一个数据,发送完之后后就complete,sample的取样周期是5秒,发现最后无输出。
可以确定当时间不足设定的时间区间时,并且发送已经完成,那么该段时间内的所有值都会被放弃
输出
2019-11-29 10:52:01.060 14950-15003/com.jimmy.rx D/TakeActivity: sample+4
2019-11-29 10:52:06.062 14950-15003/com.jimmy.rx D/TakeActivity: sample+9
2019-11-29 10:52:11.062 14950-15003/com.jimmy.rx D/TakeActivity: sample+14
2019-11-29 10:52:16.062 14950-15003/com.jimmy.rx D/TakeActivity: sample+19
2019-11-29 10:52:21.060 14950-15003/com.jimmy.rx D/TakeActivity: sample+24
2019-11-29 10:52:26.062 14950-15003/com.jimmy.rx D/TakeActivity: sample+29
throttleFirst操作符,在每个采样周期内,它总是发射原始 Observable的第一项数据,而不是最近的一项。
throttleFirst 操作符默认在 computation 调度器上执行,但是你可以使用第三个参数指定其 它的调度器。
//单击事件,2s内多次点击无效,只响应第一次。
RxView.clicks(button).throttleFirst(2, TimeUnit.SECONDS)
.subscribe(new Consumer() {
@Override
public void accept(Object o) throws Exception {
D.showShort("单击");
}
});
throttleFirst(long,TimeUnit))
throttleFirst(long,TimeUnit,Scheduler))
throttleLast操作符,在每个采样周期内,它总是发射原始 Observable的最后一项数据。
Observable.create(new ObservableOnSubscribe() {
@Override
public void subscribe(ObservableEmitter emitter) throws Exception {
for (int i = 0; i <= 31; i++) {
emitter.onNext(i + "");
Thread.sleep(1000);
}
emitter.onComplete();
}
}).subscribeOn(Schedulers.io()).throttleLast(5, TimeUnit.SECONDS).subscribe(new Consumer() {
@Override
public void accept(String s) throws Exception {
Log.d("TakeActivity", "throttlelast+" + s);
}
}, new Consumer() {
@Override
public void accept(Throwable throwable) throws Exception {
Log.d("TakeActivity", "throttlelast+" + throwable.getMessage());
}
});
输出
2019-11-29 14:21:12.206 17124-18228/com.jimmy.rx D/TakeActivity: throttlelast+4
2019-11-29 14:21:17.207 17124-18228/com.jimmy.rx D/TakeActivity: throttlelast+9
2019-11-29 14:21:22.207 17124-18228/com.jimmy.rx D/TakeActivity: throttlelast+14
2019-11-29 14:21:27.206 17124-18228/com.jimmy.rx D/TakeActivity: throttlelast+19
2019-11-29 14:21:32.207 17124-18228/com.jimmy.rx D/TakeActivity: throttlelast+24
2019-11-29 14:21:37.208 17124-18228/com.jimmy.rx D/TakeActivity: throttlelast+29
Debounce操作符,仅在过了一段指定的时间还没发射数据时才发射一个数据
Debounce 操作符会过滤掉发射速率过快的数据项。
/*2秒内连续输入的会被忽略*/
RxTextView.textChanges(edittext).debounce(2, TimeUnit.SECONDS)
.map(new Function() {
@Override
public String apply(CharSequence charSequence) throws Exception {
return charSequence.toString();
}
}).subscribe(new Consumer() {
@Override
public void accept(String s) throws Exception {
D.showShort(s);
}
});
输入框中数据发生变化并且过滤到快速连续输入,过了debounce时间之后才会触发onNext()