Android:rxjava简单实现原理(map/flatmap操作符)

article/2025/10/18 10:04:03

rxjava

  • 装饰者模式
    • 1、背景
    • 2、定义
    • 3、特征
    • 4、装饰者模式demo
  • rxjava装饰者模式
    • 1、rxjava中转换操作符map的简单实现
    • 2、rxjava中转换操作符flatmap的简单实现

装饰者模式

1、背景

假设奶茶店有两种茶,果茶(fruit tea)和奶茶(milky tea),同时这两种茶饮料可以添加不同的配料 果肉(pulp)或者蔗糖(sugar),茶品可以和配料进行组合,所以可以得到:

  • 1、pulp_fruit_tea(果茶加果肉)
  • 2、pulp_milky_tea(奶茶加果肉)
  • 3、sugar_fruit_tea(果茶加糖)
  • 4、sugar_milky_tea(奶茶加糖)
  • 5、 fruit_tea(果茶)
  • 6、milky_tea(奶茶)
    日后还会增加新的茶品和配料。

1、采用单一继承的方式的UML图: 有多少个技能就写多少个子类来继承这个tea类。
在这里插入图片描述
可以明显发现一个问题:就是随着物品修饰种类的增加,继承的类也越来越多,每增加一个技能可以组合出N个子类,那不就要加到天荒地老?
2、直接抽象一个tea类,里面包含了所有的配料。

在这里插入图片描述
这样子有多少个角色就增加多少个子类就可以了,不用根据技能增加类,避免造成子类爆炸,但是,每个角色的技能是可以叠加使用的,角色越多或者技能叠加种类越多,那么就要在超类增加越多的方法,而且直接修改超类不符合开闭原则(超类对扩展开放,对修改关闭)。

综上:

  • 装饰模式实际上是一直提倡的组合代替继承的实践方式,个人认为要理解装饰者模式首先需要理解为什么需要组合代替继承,继承又是为什么让人深恶痛绝.

为什么建议使用组合代替继承?
面向对象的特性有继承与封装,但两者却又有一点矛盾,继承意味子类依赖了父类中的实现,一旦父类中改变实现则会对子类造成影响,这是打破了封装性的一种表现. 而组合就是巧用封装性来实现继承功能的代码复用.

2、定义

1.定义:

-装饰器模式又名包装(Wrapper)模式。动态地给一个对象添加一些额外的职责。就增加功能来说,Decorator模式相比生成子类更为灵活。

  • 装饰器模式以对客户端透明的方式拓展对象的功能,是继承关系的一种替代方案。

在这里插入图片描述
UML关系图说明:

继承关系:实线、空三角箭头 ,具体装饰继承Decorator,Decorator继承Component; 聚合:实线、菱形

  • 1、抽象构件(Component)角色:一个抽象接口。装饰对象和被装饰对象【具体组件对象】共有的父类接口。这样客户端对象就能以相同的方式操作具体组件对象和装饰对象【或者说可以将装饰类作为组件类看待】

  • 2、具体构件(ConcreteComponent)角色:定义一个将要接收附加责任的类。装饰模式是为这个基类动态添加新功能。

  • 3、装饰(Decorator)角色:装饰对象包含一个真实组件对像的引用。它的作用是接受需要扩展功能的具体组件类;实现抽象组件接口,使得在动态添加功能时具体装饰类和具体组件类用法相同,使模式更加灵活。

  • 4、具体装饰(ConcreteDecorator)角色:负责给构件对象“贴上”附加的责任。

3、特征

  • 需要扩展一个类的功能或给一个类增加附加责任。
  • 需要动态地给一个对象增加功能,这些功能可以再动态地撤销。
  • 需要增加由一些基本功能的排列组合而产生的非常大量的功能

优点:

  • 1、装饰这模式和继承的目的都是扩展对象的功能,但装饰者模式比继承更灵活 通过使用不同的具体装饰类以及这些类的排列组合,设计师可以创造出很多不同行为的组合装饰者模式有很好地可扩展性
  • 2、装饰类和被装饰类可以独立发展,而不会相互耦合。Component类无须知道Decorator类,而Decorator也不用知道具体的构件,用户可以根据需要增加新的具体构件类和具体装饰类,在使用时再对其进行组合,原有代码无须改变,符合“开闭原则”。

缺点:

  • 装饰者模式会导致设计中出现许多小对象,如果过度使用,会让程序变的更复杂。并且更多的对象会是的差错变得困难,特别是这些对象看上去都很像。

4、装饰者模式demo

在这里插入图片描述

//被装饰者的对象接口
public interface Drink {public float cost();public String desc();
}
//具体的被装饰者
public class Dounai implements Drink{@Overridepublic float cost() {return 3f;}@Overridepublic String  desc() {return "纯豆奶";}
}
//装饰者的基类
public abstract class Decroator implements Drink  {private Drink drink; //要装饰的对象public Decroator(Drink drink) {this.drink = drink;}@Overridepublic float cost() {return drink.cost();}@Overridepublic String desc() {return  drink.desc();}
}
//具体的装饰者
public class Blackdou extends Decroator {public Blackdou(Drink drink) {super(drink);}@Overridepublic float cost() {return super.cost()+2f;}@Overridepublic String desc() {return super.desc()+"+黑豆";}
}
//具体的装饰者类
public class SugarDecroator extends Decroator {public SugarDecroator(Drink drink) {super(drink);}@Overridepublic float cost() {return super.cost()+1f;}@Overridepublic String desc() {return super.desc()+"+糖";}
}
//具体的装饰者类
public class SugarDecroator extends Decroator {public SugarDecroator(Drink drink) {super(drink);}@Overridepublic float cost() {return super.cost()+1f;}@Overridepublic String desc() {return super.desc()+"+糖";}
}

实验结果

这杯豆浆价格为:6.0
描述为:纯豆奶+黑豆+糖

rxjava装饰者模式

在这里插入图片描述
在这里插入图片描述

1、rxjava中转换操作符map的简单实现

Observable类

/*** 被观察者的核心抽象类* 也是使用框架的入口* @param <T>*/
public abstract class Observable<T> implements ObservableSource<T> {@Overridepublic void subscribe(Observer observer) {// 和谁建立订阅?// 怎么建立订阅?// 为了保证拓展性,交给具体的开发人员实现。这里提供一个抽象的方法subscribeActual(observer);}protected abstract void subscribeActual(Observer<T> observer);//creat操作符public  static <T> Observable<T> create(ObservableOnSubscribe<T> source){return new ObservableCreate<>(source);}//map操作符public <R> ObservableMap<T, R> map(Function<T, R> function) {return new ObservableMap<>(this, function);}//flatmap操作符public <R> ObservableFlatMap<T, R> flatMap(Function<T, ObservableSource<R>> function) {return new ObservableFlatMap<>(this, function);}
}

Observer接口

public interface Observer<T> {void onSubscribe();//建立订阅关系时候的回掉方法,什么时候和被观察者建立订阅关系,就会调用该方法void onNext(T t);void onComplete();void onError(Throwable throwable);}

ObservableCreate类

/*** 1、创建一个被观察者* 2、被观察者发射事件由具体的either发射器来完成* @param <T>*/
public class ObservableCreate<T> extends Observable<T> {final ObservableOnSubscribe<T> source;public ObservableCreate(ObservableOnSubscribe<T> source) {this.source = source;//创建一个被观察者}@Overrideprotected void subscribeActual(Observer<T> observer) {observer.onSubscribe();//建立订阅的时候调用CreateEmitter<T> emitter = new CreateEmitter<T>(observer);source.subscribe(emitter);}static class CreateEmitter<T> implements Emitter<T>{Observer<T>observer;//这里持有一个观察者,当事件发生时,直接调用该观察者对事件进行调用即可。boolean done;//互斥实现public  CreateEmitter(Observer<T> observer){this.observer = observer;}public void onNext(T t){if(done) return;observer.onNext(t);}public void onError(Throwable throwable){if(done) return;observer.onError(throwable);done = true;}public void onComplete(){if(done) return;observer.onComplete();done = true;}}}

Emitter接口

/*** 事件发射器* @param <T>*/
public interface Emitter<T> {void onNext(T t);void onComplete();void onError(Throwable throwable);
}

ObservableOnSubscribe接口

/*** 被观察者和事件发射器建立关系* 被观察者和事件之间解偶* @param <T>*/
public interface ObservableOnSubscribe<T> {void subscribe(Emitter<T> emitter);
}

ObservableSource接口

/*** 被观察者的顶层接口* @param <T>*/public interface ObservableSource<T> {void subscribe(Observer<T>observer);
}

Function接口

/*** 数据源转换函数* @param <T>* @param <R>*/
public interface Function<T,R>{R apply(T t);
}

ObservableMap

public class ObservableMap<T, U> extends AbstractObservableWithUpStream<T, U> {Function<T, U> function;public ObservableMap(ObservableSource<T> source, Function<T, U> function) {super(source);this.function = function;}@Overrideprotected void subscribeActual(Observer<U> observer) {source.subscribe(new MapObserver<>(observer,function));}static class MapObserver<T, U> implements Observer<T> {final Observer<U> downStream;final Function<T, U> mapper;public MapObserver(Observer<U> downStream, Function<T, U> mapper) {this.downStream = downStream;this.mapper = mapper;}@Overridepublic void onSubscribe() {downStream.onSubscribe();}@Overridepublic void onNext(T t){//map操作符的具体实现U u = mapper.apply(t);downStream.onNext(u);}@Overridepublic void onComplete(){downStream.onComplete();}@Overridepublic void onError(Throwable throwable){downStream.onError(throwable);}}}

AbstractObservableWithUpStream

/*** 抽象装饰类* @param <T>* @param <U>*/
public abstract class AbstractObservableWithUpStream<T,U> extends Observable<U>{protected final ObservableSource<T> source;//在这个基础上进行装饰public AbstractObservableWithUpStream(ObservableSource<T>source){this.source = source;}}

RxjavaTest

public class RxjavaTest {public static void main(String[] args) {Observable.create(new ObservableOnSubscribe<Object>() {@Overridepublic void subscribe(Emitter<Object> emitter) {System.out.println("subscribe:.....");emitter.onNext("aaaa");emitter.onNext("CCCC");emitter.onNext("ddddd");emitter.onError(new Throwable());emitter.onComplete();}}).map(new Function<Object, Object>() {@Overridepublic Object apply(Object o) {return "处理后的+ " + o;}})/*.flatMap(new Function<Object, ObservableSource<Object>>() {@Overridepublic ObservableSource<Object> apply(Object o) {return Observable.create(new ObservableOnSubscribe<Object>() {@Overridepublic void subscribe(Emitter<Object> emitter) {emitter.onNext("处理后的" + o);}});}})*/.subscribe(new Observer() {@Overridepublic void onSubscribe() {System.out.println("onSubscribe...");}@Overridepublic void onNext(Object o) {System.out.println("onNext:.... " + o);}@Overridepublic void onComplete() {System.out.println("onComplete:... ");}@Overridepublic void onError(Throwable throwable) {System.out.println("onError :... ");}});}}

实验结果

onSubscribe...
subscribe:.....
onNext:.... 处理后的:aaaa
onNext:.... 处理后的:CCCC
onNext:.... 处理后的:ddddd
onError :... 

2、rxjava中转换操作符flatmap的简单实现

ObservableFlatMap

public class ObservableFlatMap<T, U> extends AbstractObservableWithUpStream<T, U> {Function<T, ObservableSource<U>> function;public ObservableFlatMap(ObservableSource<T> source, Function<T, ObservableSource<U>> function) {super(source);this.function = function;}@Overrideprotected void subscribeActual(Observer<U> observer) {source.subscribe(new MergeObserver<>(observer, function));}static class MergeObserver<T, U> implements Observer<T> {final Observer<U> downStream;final Function<T, ObservableSource<U>> mapper;public MergeObserver(Observer<U> downStream, Function<T, ObservableSource<U>> mapper) {this.downStream = downStream;this.mapper = mapper;}@Overridepublic void onSubscribe() {downStream.onSubscribe();}@Overridepublic void onNext(T t) {ObservableSource<U> observable = mapper.apply(t);observable.subscribe(new Observer<U>() {@Overridepublic void onSubscribe() {}@Overridepublic void onNext(U u) {downStream.onNext(u);}@Overridepublic void onComplete() {}@Overridepublic void onError(Throwable throwable) {}});}@Overridepublic void onComplete() {downStream.onComplete();}@Overridepublic void onError(Throwable throwable) {downStream.onError(throwable);}}}

RxjavaTest

public class RxjavaTest {public static void main(String[] args) {Observable.create(new ObservableOnSubscribe<Object>() {@Overridepublic void subscribe(Emitter<Object> emitter) {System.out.println("subscribe:.....");emitter.onNext("aaaa");emitter.onNext("CCCC");emitter.onNext("ddddd");emitter.onError(new Throwable());emitter.onComplete();}}).flatMap(new Function<Object, ObservableSource<Object>>() {@Overridepublic ObservableSource<Object> apply(Object o) {return Observable.create(new ObservableOnSubscribe<Object>() {@Overridepublic void subscribe(Emitter<Object> emitter) {emitter.onNext("处理后的" + o);}});}}).subscribe(new Observer() {@Overridepublic void onSubscribe() {System.out.println("onSubscribe...");}@Overridepublic void onNext(Object o) {System.out.println("onNext:.... " + o);}@Overridepublic void onComplete() {System.out.println("onComplete:... ");}@Overridepublic void onError(Throwable throwable) {System.out.println("onError :... ");}});}}

实验结果

在onSubscribe...
subscribe:.....
onNext:.... 处理后的aaaa
onNext:.... 处理后的CCCC
onNext:.... 处理后的ddddd
onError :... Process finished with exit code 0

http://chatgpt.dhexx.cn/article/eXnCFtU7.shtml

相关文章

java dataset flatmap_Spark中map和flatMap的區別詳解

本文介紹了Spark中map(func)和flatMap(func)這兩個函數的區別及具體使用。 函數原型 1.map(func) 將原數據的每個元素傳給函數func進行格式化&#xff0c;返回一個新的分佈式數據集。(原文&#xff1a;Return a new distributed dataset formed by passing each element of the…

Spark中flatMap的操作

Test 1&#xff1a; package test.wyh.wordcountimport org.apache.spark.rdd.RDD import org.apache.spark.{SparkConf, SparkContext}object TestFlatMap {def main(args: Array[String]): Unit {//建立Spark连接val sparkConf new SparkConf().setMaster("local&quo…

flatMap底层实现

上篇&#xff1a;Transformation的map使用 第一种方式重写flatMap方法实现 实现需求&#xff1a;根据字符串在nc -lk 8888的窗口命令下输入的数据&#xff0c;在控制台打印输出发现&#xff1a;在同一行数据输入的单词字符串自动换行&#xff0c;按每个单词独立换行并且若输入…

java7 flatmap_flink学习之七-map、fliter、flatmap

看完了Flink的datasource、sink&#xff0c;也就把一头一尾给看完了&#xff0c;从数据流入到数据流出&#xff0c;缺少了中间的处理环节。 而flink的大头恰恰是只在这个中间环节&#xff0c;如下图&#xff1a; source-transform-sink-update.png 中间的处理环节比较复杂&…

Stream之flatMap

一、flatMap简介 flatMap:将小Stream转换为大Stream 二、示例转换要求 目标&#xff1a;将如下对象中的分类category提取出来&#xff0c;去重。其中如"哲学,爱情",需要解析为两个分类&#xff0c;["哲学","爱情"] [{"age":33,"…

flatmap使用

使用场景 适用于嵌套list数据结构&#xff0c;想把内部的list数据合并成一个list.。 举例如下&#xff1a; public class Test {public static void main(String[] args) {List<List<String>> list new ArrayList<>();List<String> list1 new Arr…

Java8中map与flatMap用法

目录 1 概述 2 map与flatMap 3 常用写法 1 概述 Java8中一些新特性在平时工作中经常会用到&#xff0c;但有时候总感觉不是很熟练&#xff0c;今天特意将这个Java8中的映射记录一下。 2 map与flatMap map---对集合中的元素逐个进行函数操作映射成另外一个 flatMap---接收一…

如何使用flatMap

1. 什么情况下用到flatMap 当使用map&#xff08;&#xff09;操作时&#xff0c;不是返回一个值&#xff0c;而是返回一个集合或者一个数组的时候&#xff0c;这时候就可以使用flatMap解决这个问题。举个例子&#xff0c;你有一个列表 [21,23,42]&#xff0c;然后你调用getPr…

【JavaScript中数组的flatMap方法的详细介绍】

在我们平时对数组进行操作的时候&#xff0c;通常map、forEach和filter方法比较常用。而flatMap方法用得相对少一些。当你掌握了flatMap方法的使用之后&#xff0c;我相信你一定会喜欢上它的&#xff01; 下面我们会通过以下三个问题展开对flatMap方法的讲解&#xff1a; 1. f…

Java8 - Streams flatMap()

文章目录 官方文档What is flatMap()?Why flat a Stream?Demo需求1&#xff1a;Find all books需求2&#xff1a;Order and LineItems需求3&#xff1a;Splits the line by spaces需求4&#xff1a; flatMap and primitive type 官方文档 https://docs.oracle.com/javase/8/…

JAVA8 中的flatmap

构建对象 class User{private String addr } 将多个User集合中的addr按照;分割合并成一个字符串list List<User> uList Lists.newArrayList();User u1 new User();u1.setAddr("a1;a2;a3;a4;a5");User u2 new User();u2.setAddr("b1;b2;b3;b4;b5&qu…

Unity resource style/Theme.AppCompat.Dialog (aka xxx:style/Theme.AppCompat.Dialog) not found

关于Unity 打包报错"resource style/Theme.AppCompat.Dialog (aka com.game.chipsmerge:style/Theme.AppCompat.Dialog) not found."的问题 解决方法: 在mainTemplate文件中添加依赖: implementation ‘com.android.support:appcompat-v7:28.0.0’ 或者自己去下载其…

android最新v7包下载,support v7 appcompat.jar包下载

android support v7 appcompat.jar包是一款非常实用的jar文件,是android开发中必备的一份文件,能够在低版本Android平台上开发一个应用程序,兼容性极强。感兴趣的朋友欢迎前来IT猫扑下载体验吧! android support v7 appcompat.jar包介绍 android-support-v7-appcompat.jar包…

解决 appcompat 1.1.0 导致 webview crash 的问题

Android SDK 太不让人省心了&#xff0c;正式版本居然也埋雷。 前段时间把 support 升级到了 androidx&#xff0c;appcompat 自动升级了新版本 androidx.appcompat:appcompat:1.1.0。 简单回归了下功能就发上线了&#xff0c;结果在在 5.1 的系统上发生了大规模的 crash&…

从AppCompat切换到MaterialComponents一些主题属性介绍

文章目录 前言主题属性颜色排版字体形状小部件ButtonsText FieldsCardsBottom Navigation 后话 前言 絮叨两句&#xff0c;感觉Component这个库有点傲娇&#xff0c;我碰到一个情景&#xff0c;使用Button&#xff0c;设置了background属性&#xff0c;当使用样式是AppCompat时…

Gradle编译问题(appcompat和material相关)

在使用Android Studio编译项目时&#xff0c;发现的编译问题。已解决&#xff0c;在此记录一下 问题1 Cant determine type for tag <macro name"m3_comp_bottom_app_bar_container_color">?attr/colorSurface</macro> 原因是androidx.appcompat:app…

Android报错之You need to use a Theme.AppCompat theme (or descendant) with this activity.

[TOC](Android报错之You need to use a Theme.AppCompat theme (or descendant) with this activity.) 一、报错如下 原因为&#xff1a;Activty继承自android.support.v7.app.AppCompatActivty,而不是android.app.Activty。 二、解决方法 看一下提示&#xff0c;就是要用Th…

appcompat_v7项目说明

一、appcompat_v7项目说明 今天来说一下appcompat_v7项目的问题&#xff0c;使用eclipse创建Android项目时&#xff0c;发现project列表中会多创建出一个appcompat_v7项目&#xff0c;这是我搭建最新的Android开发环境创建第一个Android测试项目后发现的&#xff0c;我在创建An…

Android Studio报错Could not find any version that matches com.android.support:appcompat-v7:33.+.

今天用AndroidStudio新建了一个项目&#xff0c;没想到新建项目就爆红了 而且Java代码有标红&#xff0c;cannot reslove symbol"v7" 解决方案&#xff1a; 1.打开build.gradle文件&#xff0c;找到dependencies下 implementation com.android.support:appcompat-…

Android关于Theme.AppCompat相关问题的深入分析

先来看这样一个错误&#xff1a; No resource found that matches the given name style/Theme.AppCompat.Light 对于这个错误&#xff0c;相信大部分Android开发者都遇到过&#xff0c;可能很多朋友通过百度或者Google已经解决了这个问题&#xff0c;但是网上大部分都只给出…