目录

  • 目录
  • 合并操作符
    • zip静态方法
    • zipWith
    • merge静态方法
    • mergeWith
    • combineLatest静态方法
    • withLatestFrom
    • switchMap
    • startWith
    • join
  • 条件操作
    • all
    • amb
    • contains
    • switchIfEmpty
    • defaultIfEmpty
    • sequenceEqual
    • skipUntil
    • skipWhile
    • takeUntil
    • takeWhile
  • 错误处理
    • onErrorReturn
    • resumeNext
    • retry
    • retryWhen
  • 阻塞操作
    • toList
    • toSortList
    • toMap
    • toFuture
    • blockingSubscribe
    • blockingForEach
    • blockingIterable
    • blockingFirst
    • blockingLast
    • blockingMostRecent
    • blockingSingle
  • 组合操作
    • compose
    • ConnectableObservable
      • replayObservable的方法
      • publishObservable的方法

合并操作符

zip(静态方法)

只有当原始的Observable中的每一个都发射了 一条数据时 zip 才发射数据。接受一到九个参数
Observable<Long> observable1 = Observable.interval(100, TimeUnit.MILLISECONDS).take(3).subscribeOn(Schedulers.newThread());Observable<Long> observable2 = Observable.interval(200, TimeUnit.MILLISECONDS).take(4).subscribeOn(Schedulers.newThread());Observable.zip(observable1, observable2, (aLong, aLong2) -> {System.out.print("aLong:" + aLong + "\t aLong2:" + aLong2+"\t");return aLong + aLong2;}).subscribe(o -> System.out.println("===>" + o + "\t"));
日志:
aLong:0  aLong2:0===>0
aLong:1  aLong2:1===>2
aLong:2  aLong2:2===>4

zipWith

zip的非静态写法,总是接受两个参数,第一个参数是一个Observable或者一个Iterable。
observable1.zipWith( observable2, (aLong, aLong2) -> {System.out.print("aLong:" + aLong + "\t aLong2:" + aLong2+"\t");return aLong + aLong2;
}).subscribe(o -> System.out.println("===>" + o + "\t"));

merge(静态方法)

根据时间线 合并多个observer
Observable<Long> ob1 = Observable.interval(100, TimeUnit.MILLISECONDS).take(3).subscribeOn(Schedulers.newThread());Observable<Long> ob2 = Observable.interval(50, TimeUnit.MILLISECONDS).take(3).map(aLong -> aLong + 10).subscribeOn(Schedulers.newThread());Observable.merge(ob1, ob2).subscribe(o -> System.out.print(o + "\t"));
日志结果:可以见出是根据时间线合并
10  10  0   0   11  11  12  12  1   1   2   2

mergeWith

merge非静态写法
ob1.mergeWith(ob2).subscribe(o -> System.out.print( o + "\t"));

combineLatest(静态方法)

使用一个函数结合它们最近发射的数据,然后发射这个函数的返回值,它接受二到九个Observable作为参数 或者单 个Observables列表作为参数
Observable<Long> observable1 = Observable.interval(100, TimeUnit.MILLISECONDS).take(4).subscribeOn(Schedulers.newThread());Observable<Long> observable2 = Observable.interval(200, TimeUnit.MILLISECONDS).take(5).subscribeOn(Schedulers.newThread());Observable.combineLatest(observable1, observable2, (aLong, aLong2) -> {System.out.print("aLong:" + aLong + "\t aLong2:" + aLong2+"\t");return aLong + aLong2;}).subscribe(o -> System.out.println("===>" + o + "\t"));日志:aLong:1    aLong2:0   ===>1aLong:2    aLong2:0   ===>2aLong:3    aLong2:0   ===>3aLong:3    aLong2:1   ===>4aLong:3    aLong2:2   ===>5aLong:3    aLong2:3   ===>6aLong:3    aLong2:4   ===>7

withLatestFrom

类似zip ,但是只在单个原始Observable发射了一条数据时才发射数据,而不是两个都发
但是注意 如果没有合并元素 既辅助Observable一次都没发射的时候 是不发射数据的
Observable<Long> observable2 = Observable.interval(150, TimeUnit.MILLISECONDS).take(4).subscribeOn(Schedulers.newThread());Observable.interval(100, TimeUnit.MILLISECONDS).take(3).subscribeOn(Schedulers.newThread()).withLatestFrom(observable2, (aLong, aLong2) -> {System.out.print("aLong:" + aLong + "\t aLong2:" + aLong2 + "\t");return aLong + aLong2;}).subscribe(o -> System.out.println("===>" + o + "\t"));
日志:
明明原始take是3为啥不是三条log呢 因为原始的发送0的时候 ,辅助Observable还没发送过数据
aLong:1  aLong2:0   ===>1
aLong:2  aLong2:1   ===>3

switchMap

和flatMap类似,不同的是当原始Observable发射一个新的数据(Observable)时,它将取消订阅前一个Observable
Observable.interval(500, TimeUnit.MILLISECONDS).take(3).doOnNext(aLong -> System.out.println()).switchMap(aLong -> Observable.intervalRange(aLong * 10, 3,0, 300, TimeUnit.MILLISECONDS).subscribeOn(Schedulers.newThread())).subscribe(aLong -> System.out.print(aLong+"\t"));
解析:因为发送2的时候 intervalRange发送第三条数据的时候已经是600ms既 500ms的时候原始数据发送了。导致取消订阅前一个Observable
所以 2 ,12没有发送 但是最后的22发送了 因为原始数据没有新发送的了
//        日志结果
//        0 1
//        10    11
//        20    21  22
//        而不是
//        0     1   2
//        10    11  12
//        20    21  22

startWith

是concat()的对应部分,在Observable开始发射他们的数据之前,startWith()通过传递一个参数来先发射一个数据序列
Observable.just("old")<!-- 简化版本 T item  -->.startWith("Start")<!--  多次应用探究 -->.startWith("Start2")<!--  observer -->.startWith(Observable.just("Other Observable"))<!--  Iterable -->.startWith(Arrays.asList("from Iterable"))<!--  T... -->.startWithArray("from Array", "from Array2").subscribe(s -> System.out.println(s));
日志:
from Array
from Array2
from Iterable
Other Observable
Start2
Start
old

join

任何时候,只要在另一个Observable发射的数据定义的时间窗口内,这个Observable发射了。一条数据,就结合两个Observable发射的数据

<!-- 此demo 好使但是未让能理解透彻  仅仅想测试能结果的任用  想明白的话 此demo无效 -->
Observable.intervalRange(10, 4, 0, 300, TimeUnit.MILLISECONDS).join(Observable.interval(100, TimeUnit.MILLISECONDS).take(7), aLong -> {System.out.println("开始收集:"+aLong);return Observable.just(aLong);}, aLong -> Observable.timer(200, TimeUnit.MILLISECONDS), (aLong, aLong2) -> {System.out.print("aLong:" + aLong + "\t aLong2:" + aLong2 + "\t");return aLong + aLong2;}).subscribe(aLong -> System.out.println(aLong));

条件操作

all

判定是否Observable发射的所有数据都满足某个条件
Observable.just(2, 3, 4).all(integer -> integer > 3).subscribe((aBoolean, throwable) -> System.out.println(aBoolean));
日志:false

amb

给定多个Observable,只让第一个发射数据的Observable发射全部数据
  • ambArray(静态方法):根据测试结果这个静态方法发射的最后一个
Observable.ambArray(Observable.intervalRange(0, 3, 200, 100, TimeUnit.MILLISECONDS), Observable.intervalRange(10, 3, 300, 100, TimeUnit.MILLISECONDS), Observable.intervalRange(20, 3, 100, 100, TimeUnit.MILLISECONDS)).doOnComplete(() -> System.out.println("Complete")).subscribe(aLong -> System.out.println(aLong));
日志:
20  21  22  Complete
  • ambWith:这个发射原始的
Observable.intervalRange(0, 3, 200, 100, TimeUnit.MILLISECONDS).ambWith(Observable.intervalRange(10, 3, 300, 100, TimeUnit.MILLISECONDS)).doOnComplete(() -> System.out.println("Complete")).subscribe(aLong -> System.out.println(aLong));
日志:
0   1   2   Complete

contains

判定一个Observable是否发射一个特定的值
Observable.just(2, 3, 4).contains(2).subscribe((aBoolean, throwable) -> System.out.println(aBoolean));

switchIfEmpty

如果原始Observable正常终止后仍然没有发射任何数据,就使用备用的Observable
Observable.empty().switchIfEmpty(Observable.just(2, 3, 4)).subscribe(o -> System.out.println("===>" + o + "\t")); //2,3,4

defaultIfEmpty

发射来自原始Observable的值,如果原始Observable没有发射任何值,就发射一个默认值,内部调用的switchIfEmpty。
Observable.empty().defaultIfEmpty(1).subscribe(o -> System.out.println("===>" + o + "\t")); //1

sequenceEqual

判定两个Observables是否发射相同的数据序列。(数据,发射顺序,终止状态)
Observable.sequenceEqual(Observable.just(2, 3, 4), Observable.just(2, 3, 4)).subscribe((aBoolean, throwable) -> System.out.println(aBoolean));
<!-- 它还有一个版本接受第三个参数,可以传递一个函数用于比较两个数据项是否相同。 -->
Observable.sequenceEqual(Observable.just(2, 3, 4), Observable.just(2, 3, 4), (integer, integer2) -> integer + 1 == integer2).subscribe((aBoolean, throwable) -> System.out.println(aBoolean));

skipUntil

丢弃原始Observable发射的数据,直到第二个Observable发射了一项数据
Observable.intervalRange(30, 20, 500, 100, TimeUnit.MILLISECONDS).skipUntil(Observable.timer(1000, TimeUnit.MILLISECONDS)).doOnNext(integer -> System.out.println(integer))//此时用这个主要是 测试环境 有执行时间 所以用阻塞比较好.blockingSubscribe();

skipWhile

丢弃Observable发射的数据,直到一个指定的条件不成立
Observable.just(1,2,3,4)//从2开始 因为2条件不成立.skipWhile(aLong -> aLong==1).doOnNext(integer -> System.out.println(integer))//此时用这个主要是 测试环境 有执行时间 所以用阻塞比较好.blockingSubscribe();

takeUntil

当第二个Observable发射了一项数据或者终止时,丢弃原始Observable发射的任何数据
<!-- 条件变体 -->
Observable.just(2,3,4,5).takeUntil(integer ->  integer<=4)
             .subscribe(o -> System.out.print(o + "\t"));//2,3,4
<!-- Observable变体 -->
Observable.intervalRange(30, 20, 500, 100, TimeUnit.MILLISECONDS).takeUntil(Observable.timer(1000, TimeUnit.MILLISECONDS)).doOnNext(integer -> System.out.println(integer)).doOnComplete(() -> System.out.println("Complete"))//此时用这个主要是 测试环境 有执行时间 所以用阻塞比较好.blockingSubscribe();

takeWhile

发射Observable发射的数据,直到一个指定的条件不成立
Observable.just(2,3,4,5).takeWhile(integer ->integer<=4 ).subscribe(o -> System.out.print(o + "\t"));//2,3

错误处理

onErrorReturn

让Observable遇到错误时发射一个特殊的项并且正常终止
<!-- 遇到错误处理范例 -->
Observable.error(new Throwable("我擦 空啊")).onErrorReturnItem("hei").subscribe(o -> System.out.println("===>" + o + "\t"), throwable -> System.out.println("===>throwable"), () -> System.out.println("===>complete"));
日志:
===>hei
===>complete
<!--  遇到错误不处理范例 -->Observable.error(new Throwable("我擦 空啊")).onErrorReturn(throwable -> {System.out.println("错误信息:" + throwable.getMessage());return throwable;}).subscribe(o -> System.out.println("===>" + o + "\t"), throwable -> System.out.println("===>throwable"), () -> System.out.println("===>complete"));
日志:
错误信息:我擦 空啊
===>java.lang.Throwable: 我擦 空啊
===>complete

resumeNext

让Observable在遇到错误时开始发射第二个Observable的数据序列
  • onErrorResumeNext:可以处理所有的错误
Observable.error(new Throwable("我擦 空啊")).onErrorResumeNext(throwable -> {System.out.println("错误信息:" + throwable.getMessage());return Observable.range(0, 3);}).subscribe(o -> System.out.print("===>" + o + "\t"), throwable -> System.out.print("===>throwable"+ "\t"), () -> System.out.print("===>complete"+ "\t"));日志:错误信息:我擦 空啊===>0 ===>1   ===>2   ===>complete
  • onExceptionResumeNext:只能处理异常
    Throwable 不是一个 Exception ,它会将错误传递给观察者的 onError 方法,不会使用备用 的Observable。
<!-- Throwable不能处理范例 -->
Observable.error(new Throwable("我擦 空啊")).onExceptionResumeNext(observer -> Observable.range(0, 3)).subscribe(o -> System.out.println("===>" + o + "\t"), throwable -> System.out.println("===>throwable"), () -> System.out.println("===>complete"));日志:===>throwable<!-- 正确演示范例 无效ing 求解答~ todo -->

retry

如果原始Observable遇到错误,重新订阅它期望它能正常终止
  • 变体count 重复次数
Observable.create(e -> {e.onNext(1);e.onNext(2);e.onError(new Throwable("hehe"));}).retry(2).subscribe(o -> System.out.print("===>" + o + "\t"), throwable -> System.out.print("===>throwable\t"), () -> System.out.print("===>complete\t"));日志:===>1  ===>2   ===>1   ===>2   ===>1   ===>2   ===>throwable
  • 变体Predicate 条件判定 如果返回 true retry,false 放弃 retry
Observable.create(e -> {e.onNext(1);e.onNext(2);e.onError(new Throwable("hehe"));}).retry(throwable -> throwable.getMessage().equals("hehe1")).subscribe(o -> System.out.print("===>" + o + "\t"), throwable -> System.out.print("===>throwable\t"), () -> System.out.print("===>complete\t"));日志:
===>1   ===>2   ===>throwable

retryWhen

需要一个Observable 通过判断 throwableObservable,Observable发射一个数据 就重新订阅,发射的是 onError 通知,它就将这个通知传递给观察者然后终止。
<!-- 正常范例 -->Observable.just(1, "2", 3).cast(Integer.class)<!-- 结果:1,1,complete 原因这个Observable发了一次数据 -->.retryWhen(throwableObservable -> Observable.timer(1, TimeUnit.SECONDS))<!-- 结果:1,1,1,1,complete 原因这个Observable发了三次数据 -->.retryWhen(throwableObservable -> Observable.interval(1, TimeUnit.SECONDS).take(3)).subscribe(o -> System.out.println("retryWhen 1===>" + o + "\t"), throwable -> System.out.println("retryWhen 1===>throwable"), () -> System.out.println("retryWhen 1===>complete"));<!-- 通过判断throwable 进行处理范例 -->Observable.just(1, "2", 3).cast(Integer.class).retryWhen(throwableObservable -> {return throwableObservable.switchMap(throwable -> {if (throwable instanceof IllegalArgumentException)return Observable.just(throwable);<!-- 这种方式OK -->
//                        else{
//                            PublishSubject<Object> pb = PublishSubject.create();
//                            pb .onError(throwable);
//                            return pb;
//                        }else//方法泛型return Observable.<Object>error(throwable);<!-- 这种方式也OK -->
//                        return Observable.just(1).cast(String.class);});}).subscribe(o -> System.out.println("retryWhen 2===>" + o + "\t"), throwable -> System.out.println("retryWhen 2===>throwable"), () -> System.out.println("retryWhen 2===>complete"));
日志:
retryWhen 2===>1
retryWhen 2===>throwable

阻塞操作

toList

Observable.just(1, 2, 3).toList().blockingGet().forEach(aLong -> System.out.println(aLong));

toSortList

Observable.just(5, 2, 3).toSortedList().blockingGet().forEach(integer -> System.out.println(integer))

toMap

Map<String, Integer> map = Observable.just(5, 2, 3)
//                .toMap(integer -> integer + "_")//key 就是5_,value就是5+10   mapSupplier map提供者.toMap(integer -> integer + "_", integer -> integer + 10, () -> new HashMap<>()).blockingGet();

toFuture

这个操作符将Observable转换为一个返 回单个数据项的 Future 带有返回值的任务
如果原始Observable发射多个数据项, Future 会收到1个 IllegalArgumentException
如果原始Observable没有发射任何数据, Future 会收到一 个 NoSuchElementException
如果你想将发射多个数据项的Observable转换为 Future ,可以这样 用: myObservable.toList().toFuture()
Observable.just(1, 2, 3).toList()//转换成Single<List<T>> 这样就变成一个数据了.toFuture().get().forEach(integer -> System.out.println(integer));

blockingSubscribe

Observable.just(1, 2, 3).blockingSubscribe(integer -> System.out.println(integer));

blockingForEach

对BlockingObservable发射的每一项数据调用一个方法,会阻塞直到Observable完成。
Observable.interval(100, TimeUnit.MILLISECONDS).doOnNext(aLong -> {if (aLong == 10)throw new RuntimeException();}).onErrorReturnItem(-1L).blockingForEach(aLong -> System.out.println(aLong));

blockingIterable

Observable.just(1, 2, 3).blockingIterable()
//                .blockingIterable(5);.forEach(aLong -> System.out.println("aLong:" + aLong));

blockingFirst

Observable.empty()// .blockingFirst();//带默认值版本.blockingFirst(-1));

blockingLast

Observable.just(1,2,3)// .blockingLast();//带默认值版本.blockingLast(-1));

blockingMostRecent

返回一个总是返回Observable最近发射的数据的Iterable,类似于while的感觉
Iterable<Long> c = Observable.interval(100, TimeUnit.MILLISECONDS).doOnNext(aLong -> {if (aLong == 10)throw new RuntimeException();}).onErrorReturnItem(-1L).blockingMostRecent(-3L);
for (Long aLong : c) {System.out.println("aLong:" + aLong);}
日志很长 可以自己一试变知

blockingSingle

终止时只发射了一个值,返回那个值
empty 无默认值 报错, 默认值的话显示默认值
多个值的话 有无默认值都报错
System.out.println("emit 1 value:" + Observable.just(1).blockingSingle());
System.out.println("default empty single:" + Observable.empty().blockingSingle(-1));
System.out.println("default emit 1 value:" + Observable.just(1).blockingSingle(-1));
try {System.out.println("empty single:" + Observable.empty().blockingSingle());System.out.println("emit many value:" + Observable.just(1, 2).blockingSingle());System.out.println("default emit many value:" + Observable.just(1, 2).blockingSingle(-1));
} catch (Exception e) {e.printStackTrace();
}
日志:
emit 1 value:1
default empty single:-1
default emit 1 value:1
java.util.NoSuchElementException

组合操作

compose

有多个 Observable ,并且他们都需要应用一组相同的 变换
<!--  用一个工具类去写 这样符合单一职责 -->
//composes 工具类
public class RxComposes {public static <T> ObservableTransformer<T, T> applyObservableAsync() {return upstream -> upstream.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread());}
}Observable.empty().compose(RxComposes.applyObservableAsync()).subscribe(integer -> System.out.println("ob3:" + integer));

ConnectableObservable

可连接的Observable在 被订阅时并不开始发射数据,只有在它的 connect() 被调用时才开始用这种方法,你可以 等所有的潜在订阅者都订阅了这个Observable之后才开始发射数据。即使没有任何订阅者订阅它,你也可以使用 connect 让他发射

replay(Observable的方法)

每次订阅 都对单个订阅的重复播放一边
  • bufferSize:对源发射队列的缓存数量, 从而对新订阅的进行发射

    Observable的方法 返回是ConnectableObservable
    切记要让ConnectableObservable具有重播的能力,必须Obserable的时候调用replay,而不是ConnectableObservable 的时候调用replay

//this  is  OK,too!ConnectableObservable<Integer> co = Observable.just(1, 2, 3)//类似 publish直接转成 ConnectableObservable  切记要重复播放的话必须Obserable的时候调用replay//而不是ConnectableObservable 的时候调用replay 所以 .publish().replay()则无效.replay(3);//重复播放的 是1  2  3
//           .replay(2);//重复播放的 是 2  3co.doOnSubscribe(disposable -> System.out.print("订阅1:")).doFinally(() -> System.out.println()).subscribe(integer -> System.out.print(integer + "\t"));co.connect();//此时开始发射数据 不同与 refCount 只发送一次co.doOnSubscribe(disposable -> System.out.print("订阅2:")).doFinally(() -> System.out.println()).subscribe(integer -> System.out.print(integer + "\t"));co.doOnSubscribe(disposable -> System.out.print("订阅3:")).doFinally(() -> System.out.println()).subscribe(integer -> System.out.print(integer + "\t"));
replay(3)日志:只能缓存原始队列的两个【1,2,3】
订阅1:1   2   3
订阅2:1   2   3
订阅3:1   2   3
replay(2)日志:只能缓存原始队列的两个【2,3】
订阅1:1   2   3
订阅2:    2   3
订阅3:    2   3

publish(Observable的方法)

将普通的Observable转换为可连接的Observable
ConnectableObservable<Integer> co = Observable.just(1, 2, 3).publish();co.subscribe(integer -> System.out.println("订阅1:" + integer));co.subscribe(integer -> System.out.println("订阅2:" + integer));co.subscribe(integer -> System.out.println("订阅3:" + integer));co.connect();//此时开始发射数据
  • refCount(ConnectableObservable的方法): 操作符把从一个可连接的Observable连接和断开的过程自动化了, 就像reply的感觉式样 每次订阅 都对单个订阅的重复播放一边
Observable<Integer> co = Observable.just(1, 2, 3).publish()//类似于reply  跟时间线有关  订阅开始就开始发送.refCount();co.doOnSubscribe(disposable -> System.out.print("订阅1:")).doFinally(() -> System.out.println()).subscribe(integer -> System.out.print(integer + "\t"));co.doOnSubscribe(disposable -> System.out.print("订阅2:")).doFinally(() -> System.out.println()).subscribe(integer -> System.out.print(integer + "\t"));Observable.timer(300, TimeUnit.MILLISECONDS).doOnComplete(() -> {co.doOnSubscribe(disposable -> System.out.print("订阅3:")).doFinally(() -> System.out.println()).subscribe(integer -> System.out.print(integer + "\t"));}).blockingSubscribe();
日志:
订阅1:1   2   3
订阅2:1   2   3
订阅3:1   2   3

RxJava2总结之操作详解(三)相关推荐

  1. python输入参数改变图形_Python基于Tensor FLow的图像处理操作详解

    本文实例讲述了Python基于Tensor FLow的图像处理操作.分享给大家供大家参考,具体如下: 在对图像进行深度学习时,有时可能图片的数量不足,或者希望网络进行更多的学习,这时可以对现有的图片数 ...

  2. python对输入的字符串进行解析_python数据类型_字符串常用操作(详解)

    这次主要介绍字符串常用操作方法及例子 1.python字符串 在python中声明一个字符串,通常有三种方法:在它的两边加上单引号.双引号或者三引号,如下: name = 'hello' name1 ...

  3. Android init.rc文件解析过程详解(三)

    Android init.rc文件解析过程详解(三) 三.相关结构体 1.listnode listnode结构体用于建立双向链表,这种结构广泛用于kernel代码中, android源代码中定义了l ...

  4. Windows 7防火墙设置详解(三)

    Windows 7防火墙设置详解(三) 一.如何禁用或启用规则 方法:只需要在需要禁用或启动的规则上,鼠标右键选择启用或禁止规则即可,或点击右侧的操作栏进行规则启用或禁止. 二.入站规则和出站规则 由 ...

  5. 最全整理!Python 操作 Excel 库 xlrd与xlwt 常用操作详解!

    来源/早起Python 在之前的Python办公自动化系列文章中,我们已经相信介绍了openyxl.xlsxwriter等Python操作Excel库. 相信大家对于几个库的差异与使用场景有了一定的认 ...

  6. python怎么重命名word文件,Python读取word文本操作详解

    本文研究的主要问题时Python读取word文本操作,分享了相关概念和实现代码,具体如下. 一,docx模块 Python可以利用python-docx模块处理word文档,处理方式是面向对象的.也就 ...

  7. python列表切片后得到剩余列表_python列表切片和嵌套列表取值操作详解

    python列表切片和嵌套列表取值操作详解 给出列表切片的格式: [开头元素::步长] # 输出直到最后一个元素,(最后一个冒号和步长可以省略,下同) [开头元素:结尾元素(不含):步长] # 其中, ...

  8. HTML对字体的操作详解

    摘自:HTML对字体的所有操作详解(经典) 作者:HeroKern 发布时间: 2016-01-31 21:15:31 网址:https://blog.csdn.net/qq_21792169/art ...

  9. 红黑树操作详解——很形象的过程

    红黑树是一种很好的自平衡二叉排序树,在此,给出一个网友给出的红黑树操作详解: https://segmentfault.com/a/1190000012728513 里面给出了红黑树的详细操作,过程很 ...

最新文章

  1. linux平台调试终端,10款Linux平台上优秀的调试器,总有一款适合你!
  2. [Nancy On .Net Core Docker] 轻量级的web框架
  3. 科学为什么重要?马化腾公开信引热议,透露企业未来发展方向
  4. 实战项目五:抓取简书文章信息
  5. POJ3185 The Water Bowls(反转法or dfs 爆搜)
  6. linux日志服务是哪个,『学了就忘』Linux日志管理 — 2.日志服务rsyslogd
  7. virtual background for conference
  8. 异步通信在生活中的例子_聊聊工作中经常遇到的“异步”,你掌握了多少
  9. I2c 诊断深入解析
  10. 03_MySQL多表事务课堂笔记
  11. 揭秘“清华园”的“N”种打开方式!
  12. stl min函数_std :: min_element()函数以及C ++ STL中的示例
  13. 卡西欧计算机怎么传程序,卡西欧计算器程序传输软件fa-124的使用方法
  14. talib如何安装方法
  15. proteus8.6安装包,单片机仿真软件
  16. 小程序应用 饿了么美团外卖cps领券返利小程序+前端(带三级分销裂变)
  17. python中def main是什么意思_python - 为什么要使用def main()?
  18. SpringCloud的注册中心
  19. 千呼万唤始出来的CoordinatorLayout
  20. 柔性电子综述2012 ---在医疗,汽车行业,人机界面,移动设备以及其他场景下的可能应用

热门文章

  1. java 找不到符号_java找不到符号
  2. html用图片代替列表,Html列表与图片的应用
  3. html5 励志名言,励志名言
  4. android平板专区,平板电脑QQ空间HD( Android Pad )1.0
  5. CephFS性能基准测试与集群优化 | 万字总结
  6. 【web前端特效源码】使用HTML5+CSS3+JavaScript制作一个果冻导航标签栏图标按钮效果~~适合初学者~超简单~ |前端开发|IT软件
  7. 枫之谷虚拟机登不进去怎么办 新枫之谷无法登入怎么办,登入问题解决办法汇总
  8. Python网络编程--Echo服务
  9. utools,一款提高办公效率软件
  10. 魔幻冒险类VR游戏《无界术士》即将登陆Steam平台