Android工厂设计模式(简单工厂,工厂方法,抽象工厂,BitmapFactory简单工厂分析,Retrofit抽象工厂分析)

article/2025/8/24 23:47:02

文章目录

    • 创建型设计模式(简单工厂,工厂方法,抽象工厂)
      • 一.简单工厂模式
        • 引出简单工厂模式
      • 二.工厂方法模式
      • 三.抽象工厂模式
    • Android源码中用到的工厂模式举例
      • 一.BitmapFactory 源码工厂模式详解(简单工厂)
      • 二.Retrofit的工厂模式(抽象工厂)

创建型设计模式(简单工厂,工厂方法,抽象工厂)

工厂模式主要是用于对对象实例化的一种管理模式,一般情况下,我们都需要使用new关键字来创建一个对象,那么我们就需要用工厂模式来统一管理我们对象的创建过程,把对象的创建交给该模式去处理,这样我们就不用手动的去new对象了,工厂模式主要是将创建对象的具体过程屏蔽隔离起来。

首先我们先来看一个Android里面开发常用的例子SharedPreferences。这是布局文件

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".simple1.MainActivity"><TextViewandroid:id="@+id/infoTv"android:onClick="getInfo"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Hello World!"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toTopOf="parent" /></androidx.constraintlayout.widget.ConstraintLayout>

我们一般都这么写,常规写法

public class MainActivity extends AppCompatActivity {TextView textView;private SharedPreferences preferences;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);textView = findViewById(R.id.infoTv);//模拟用SP存入数据SPUtils.getInstance().putString("username", "Colin").putString("userAge", "33").commit();}//这里是模拟从SP取出我们想要的数据展示在UI上public void getInfo(View view) {String username = SPUtils.getInstance().getString("username", "");String userAge = SPUtils.getInstance().getString("userAge", "");textView.setText("username=" + username + "userAge=" + userAge);}
}

SP工具类

public class SPUtils {private SharedPreferences.Editor editor;private SharedPreferences preferences;private volatile static SPUtils mInstance;private SPUtils() {}public static SPUtils getInstance() {if (mInstance == null) {synchronized (SPUtils.class) {if (mInstance == null) {mInstance = new SPUtils();}}}return mInstance;}public void init(Context context) {preferences = context.getSharedPreferences("Cache", Context.MODE_PRIVATE);editor = preferences.edit();}public SPUtils putString(String key, String value) {editor.putString(key, value);return this;}public void commit() {editor.commit();}public String getString(String key, String defaultStr) {return preferences.getString(key, defaultStr);}
}

初始化

public class MyApp extends Application {@Overridepublic void onCreate() {super.onCreate();SPUtils.getInstance().init(this);}
}

小结:

优点:通过SPUtils工具类来优化代码,就不用每次都在Activity里面重复写SP的代码了,做到了统一管理。

缺点:不能灵活改变获取数据的方式。数据如果更换成内存,或者数据库,MMKV的方式存取,那么就要将上面用到SP的地方都换掉,换成内存换成,数据库的方式存储的话,那么我们需要改动的代码就很多。

一.简单工厂模式

其实我觉得简单工厂模式是一种书写的思维习惯,不太像真实的软件设计模式。

由上面的例子引出下面这幅图。假设我们有4中方式操作数据,那么我们复写4份不同的代码,那就很无语了;那么我们可以定义一套规则,有写入数据,取出数据的操作,然后再交给不同方式的不同对象去处理就好。
在这里插入图片描述


/**
定义好写入数据和读取数据的接口,类似于一种规则,
都是我们常见的数据类型,
*/
public interface IOHandler {//写数据void put(String key, String value);void put(String key, int value);void put(String key, long value);void put(String key, boolean value);void put(String key, Object value);void put(String key, double value);void put(String key, float value);//读取数据String getString(String key);Double getDouble(String key);boolean getBoolean(String key);float getFloat(String key);int getInt(String key);Object getObject(String key);long getLong(String key);
}

我们这里搞一个SP的实现类,实现上面我们写的接口

/**这个类的含义是通过SP的方式对数据进行读取
**/
public class SPIOHandler implements IOHandler {@Overridepublic void put(String key, String value) {//写数据,通过上面我们封装好的SPUtils工具类,相当于又加了一层封装//到时候我们直接调用SPIOHandler的put方法就行,其他都不用管了SPUtils.getInstance().putString(key, value).commit();}@Overridepublic void put(String key, int value) {}@Overridepublic void put(String key, long value) {}@Overridepublic void put(String key, boolean value) {}@Overridepublic void put(String key, Object value) {}@Overridepublic void put(String key, double value) {}@Overridepublic void put(String key, float value) {}@Overridepublic String getString(String key) {//获取数据也是一样return SPUtils.getInstance().getString(key, "");}@Overridepublic Double getDouble(String key) {return null;}@Overridepublic boolean getBoolean(String key) {return false;}@Overridepublic float getFloat(String key) {return 0;}@Overridepublic int getInt(String key) {return 0;}@Overridepublic Object getObject(String key) {return null;}@Overridepublic long getLong(String key) {return 0;}
}

这里我们模拟两种方式对数据的存取,一个是SP,一个是下面这个内存的形式。

/*** IOHandler的实现类,利用内存的方式对数据进行写入和读取*/
public class MemoryIOHandler implements IOHandler {//这里是一个缓存对象,可以对图片数据进行缓存,下次我们取图片的时候就不用再去请求网络了//可以直接从缓存拿LruCache<String, Object> mCache = new LruCache<>(10 * 1024 * 1024);@Overridepublic void put(String key, String value) {mCache.put(key, value);}@Overridepublic void put(String key, int value) {mCache.put(key, value);}@Overridepublic void put(String key, long value) {mCache.put(key, value);}@Overridepublic void put(String key, boolean value) {mCache.put(key, value);}@Overridepublic void put(String key, Object value) {mCache.put(key, value);}@Overridepublic void put(String key, double value) {mCache.put(key, value);}@Overridepublic void put(String key, float value) {mCache.put(key, value);}@Overridepublic String getString(String key) {return (String) mCache.get(key);}@Overridepublic Double getDouble(String key) {return (Double) mCache.get(key);}@Overridepublic boolean getBoolean(String key) {return (boolean) mCache.get(key);}@Overridepublic float getFloat(String key) {return 0;}@Overridepublic int getInt(String key) {return 0;}@Overridepublic Object getObject(String key) {return null;}@Overridepublic long getLong(String key) {return 0;}
}

在一开始我们是这样写入数据的。(写入数据举例,读取数据亦是如此)

SPUtils.getInstance().putString("username", "Colin").putString("userAge", "33").commit();

现在我们可以改成这样,通过我们封装的接口引用指向对应实现的子类对象

private IOHandler ioHandler;
ioHandler = new SPIOHandler();
ioHandler.put("username", "Colin");
ioHandler.put("userAge", "33");

我们这里切换也是非常方便的,前面说的我们获取数据也有可能用其他方法获取,比如上面说的内存方式,此时我们可以直接切换实现类即可。

ioHandler = new MemoryIOHandler();
ioHandler.put("username", "Colin");
ioHandler.put("userAge", "33");

这种写法:

优点:用不同的方式去写入读取数据都不需要关注它的具体实现,我们只需要切换对应的实现类就可以实现同样的逻辑。

缺点:在Activity上需要使用到这个类的时候都要手动去new对象。

引出简单工厂模式

从上面的代码可以看出,我们的UI界面每次都要在用到的地方new对象,对创建对象的依赖性太强,为了减少Activity对创建对象的依赖,我们定义一个工厂类,我们需要什么对象就传入对应的类型匹配即可。

/*** IOHandler工厂,帮助我们创建具体的实现了IOHandler的类*/
public class IOHandlerFactory {public enum IOType {PREFERENCES, MEMORY}//创建具体的IOHandler子类对象public static IOHandler createIOHandle(IOType ioType) {IOHandler ioHandler = null;switch (ioType) {case PREFERENCES:ioHandler = new SPIOHandler();break;case MEMORY:ioHandler = new MemoryIOHandler();break;}return ioHandler;}
}

来看下我们调用:

跟我们上面的其实大同小异,都是获取对应的对象,但是这里的优点是隐藏了对象的创建,解除了Activity和new实例的耦合,把创建对象的动作交给了我们定义好的工厂类,这就是简单工厂模式。

ioHandler = IOHandlerFactory.createIOHandle(IOHandlerFactory.IOType.PREFERENCES);
ioHandler.put("username", "Colin");
ioHandler.put("userAge", "33");

简单总结

优点:我们可以对创建的对象进行一些 “加工” ,而且调用方并不知道,因为工厂隐藏了这些细节,没有工厂的话,那我们就得自己在UI上写这些代码

缺点:每次增加子类或者删除子类对象的创建都需要打开这简单工厂类来进行修改,违反了我们的开闭原则,我们尽量不要修改已封装好的基类,简单来说就是不方便代码扩展,要修改的地方太多。

二.工厂方法模式

根据上面的前提我们优化一下代码,尽量保证面向接口编程。工厂方法模式是对简单工厂模式进一步的解耦,在工厂方法模式中是一个子类对应一个工厂类,而这些工厂类都实现于一个抽象接口IOFactory,这样就避免了简单工厂模式,代码都在一个工厂类里面,拆分成了一个个的工厂小类,用到哪个类就使用它对应的工厂类就行。

//定义工厂生产IOHandle需要遵守的规则
public interface IOFactory {IOHandler createIOHandler();
}
//SP的对象创建过程我们放到一个工厂类里面
public class SPIOFactory implements IOFactory {@Overridepublic IOHandler createIOHandler() {return new SPIOHandler();}
}
//内存方式的对象也是如此
public class MemoryIOFactory implements IOFactory {@Overridepublic IOHandler createIOHandler() {return new MemoryIOHandler();}
}

对比一下调用方式:

private IOHandler ioHandler;
/**这里我们通过实例化对应的SP工厂类,再通过工厂ioFactory对象调用createIOHandler返回的就是我们所需要的
IOHandler的子类的对象*/
IOFactory ioFactory = new SPIOFactory();
//IOFactory ioFactory = new MemoryIOFactory();当我们需要某个类的对象时候,直接替换它所对应的小工厂类即可ioHandler = ioFactory.createIOHandler();ioHandler.put("username", "Colin");ioHandler.put("userAge", "33");

优点:各个不同功能的实例对象的创建代码,也没有耦合在同一个工厂类里,而是抽象了一个工厂接口作为扩展点,这也是工厂方法模式对简单工厂模式解耦的一个体现。

缺点:工厂方法模式的缺点是每增加一个java类,就需要增加一个对应的工厂类,当我们的类很多的时候,那么对应的工厂类也会很多。

三.抽象工厂模式

基于工厂方法的进一步优化的方式。

public class IOHandlerFactory {
//帮助我们创建对象通过传入的.class判断我们需要的类进而创建对应的对象public static <T extends IOHandler> IOHandler createIOHandle(Class<T> tClass) {IOHandler ioHandler = null;try {ioHandler = tClass.newInstance();} catch (IllegalAccessException e) {e.printStackTrace();} catch (InstantiationException e) {e.printStackTrace();}return ioHandler;}//这里举个SP例子public static IOHandler createSharePreferences() {return createIOHandle(SPIOHandler.class);}//...往下我们需要什么类的对象,就封装一个它对应的方法,外部直接调用即可。
}

调用:

private IOHandler ioHandler;ioHandler = IOHandlerFactory.createSharePreferences();ioHandler.put("username", "Colin");ioHandler.put("userAge", "33");

优点:相比于工厂方法模式不用一直创建新的对应的类的小工厂,扩展性更加,不会使代码越来越多,越复杂,把生产对象的过程抽象化,这样就可以和业务逻辑解耦,如果有新扩展,可以在IOHandlerFactory中增加对应的方法。

缺点:暂无。

Android源码中用到的工厂模式举例

一.BitmapFactory 源码工厂模式详解(简单工厂)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6eWBLcM3-1670077238626)(C:\Users\qiufh\Desktop\ff0aa6069cf62e419a2eaec1ad3e1a4.jpg)]

我们先看一下BitmapFactory 这个类里面具有的一些方法,快捷键ctrl+F12可查看当前类里面的方法,看到这我们就知道主要都是一些解码操作的方法,最后都是通过解析传入的图片的资源,最后转化成Bitmap对象。

接下来我们看一下BitmapFactory 生成 Bitmap的调用的过程吧,一开始我们调用的是这个方法传入资源的路径,然后往下走decodeFile(pathName, null);最后返回的是Bitmap,所以我们往下走bm = decodeStream(stream, null, opts);

public static Bitmap decodeFile(String pathName) {return decodeFile(pathName, null);
}public static Bitmap decodeFile(String pathName, Options opts) {validate(opts);Bitmap bm = null;InputStream stream = null;try {stream = new FileInputStream(pathName);bm = decodeStream(stream, null, opts);} catch (Exception e) {/*  do nothing.If the exception happened on open, bm will be null.*/Log.e("BitmapFactory", "Unable to decode stream: " + e);} finally {if (stream != null) {try {stream.close();} catch (IOException e) {// do nothing here}}}return bm;}

进到decodeStream(stream, null, opts);方法里面看看,

@Nullable
public static Bitmap decodeStream(@Nullable InputStream is, @Nullable Rect outPadding,@Nullable Options opts) {// we don't throw in this case, thus allowing the caller to only check// the cache, and not force the image to be decoded.if (is == null) {return null;}validate(opts);Bitmap bm = null;Trace.traceBegin(Trace.TRACE_TAG_GRAPHICS, "decodeBitmap");try {if (is instanceof AssetManager.AssetInputStream) {final long asset = ((AssetManager.AssetInputStream) is).getNativeAsset();bm = nativeDecodeAsset(asset, outPadding, opts, Options.nativeInBitmap(opts),Options.nativeColorSpace(opts));} else {bm = decodeStreamInternal(is, outPadding, opts);}if (bm == null && opts != null && opts.inBitmap != null) {throw new IllegalArgumentException("Problem decoding into existing bitmap");}setDensityFromOptions(bm, opts);} finally {Trace.traceEnd(Trace.TRACE_TAG_GRAPHICS);}return bm;
}

我们看看这行代码,很明显它的通过JNI调用了底层的方法来进行解码,这里我们暂时不深究,最后它是返回一个Bitmap对象,

bm = nativeDecodeAsset(asset, outPadding, opts, Options.nativeInBitmap(opts),Options.nativeColorSpace(opts));

生成Bitmap的大致的流程我们都过了一边,其实我们不必深究太多源码,我们调用者只需要知道我们传入图片的路径会返回一个Bitmap就行,而正是因为它使用了工厂模式,把这些细节都屏蔽了,所以我们不用操心,甭管它生成的,我给你一个图片路径你给我生成一个 Bitmap 就好了。

说到这里,可能大家还不明白这玩玩意儿哪里体现工厂模式了,不慌,接下来继续分析。BitmapFactory,通过传入不同的条件,得到同样的bitmap,回顾我们上面说的简单工厂模式,是不是传入我们想要的type类型就可以从工厂里面生产出我们想要的实例对象,这是不是很类似呢。看下面的代码,最终都是为的是生成Bitmap对象但是我们可以传入不同的条件参数进行获取,我们都可以理解为在同一个工厂用不同的条件去生产相同的产品。

简单工厂模式的实质是由一个工厂类根据传入的参数,动态决定应该创建哪一个产品类(这些产品类继承自一个父类或接口)的实例

但是这样的简单工厂模式缺点很明显,比如我们有另外一种生产Bitmap的方法出现的时候,我们就要去修改工厂类BitmapFactory,违反了开闭原则,我们尽量不要去修改我们的基类。

/*** Creates Bitmap objects from various sources, including files, streams,* and byte-arrays.*/
public class BitmapFactory {public static Bitmap decodeFile(String pathName, Options opts){......}public static Bitmap decodeFile(String pathName) {......}public static Bitmap decodeResourceStream(Resources res, TypedValue value,InputStream is, Rect pad, Options opts) {......}public static Bitmap decodeResource(Resources res, int id, Options opts) {......}public static Bitmap decodeResource(Resources res, int id) {......}public static Bitmap decodeByteArray(byte[] data, int offset, int length, Options opts){......}public static Bitmap decodeByteArray(byte[] data, int offset, int length) {......}public static Bitmap decodeStream(InputStream is, Rect outPadding, Options opts) {......}public static Bitmap decodeStream(InputStream is) {......}public static Bitmap decodeFileDescriptor(FileDescriptor fd, Rect outPadding, Options opts) {......}public static Bitmap decodeFileDescriptor(FileDescriptor fd) {......}
}

二.Retrofit的工厂模式(抽象工厂)

由于Retrofit涉及的源码比较庞大,在这里仅仅举例介绍这个框架里面所应用到的工厂模式吗,下面是Retrofit的简单使用方式,我们简单分析一下GsonConverterFactory.create()和RxJavaCallAdapterFactory.create(),很明显从名字上就可以看出是工厂模式。两者创建的形式都是抽象工厂模式,大同小异,拿GsonConverterFactory.create()举例说明,请看下文。

new Retrofit.Builder().baseUrl("https://www.baidu.com/").client(new OkHttpClient()).addConverterFactory(GsonConverterFactory.create()).addCallAdapterFactory(RxJavaCallAdapterFactory.create()).build();

我们点击create()方法来到源码中,

public final class GsonConverterFactory extends Converter.Factory {public static GsonConverterFactory create() {return create(new Gson());}

点击这里进入到抽象工厂中看看,

Converter.Factory

可以看到Factory是abstract修饰,那么就可以明确它是使用的是抽象工厂。

//这是个数据的转换器的抽象类,泛型F表示输入的参数,T是输出的参数,也就是我们转换完成之后的数据类型。
public interface Converter<F, T> {//这是一个接口里面的方法,主要做的是转换的操作@Nullable T convert(F value) throws IOException;abstract class Factory {//请求响应public @Nullable Converter<ResponseBody, ?> responseBodyConverter(Type type,Annotation[] annotations, Retrofit retrofit) {return null;}//发起请求public @Nullable Converter<?, RequestBody> requestBodyConverter(Type type,Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {return null;}//该工厂用于转换字符串类型的转换器,public @Nullable Converter<?, String> stringConverter(Type type, Annotation[] annotations,Retrofit retrofit) {return null;}protected static Type getParameterUpperBound(int index, ParameterizedType type) {return Utils.getParameterUpperBound(index, type);}protected static Class<?> getRawType(Type type) {return Utils.getRawType(type);}}
}

接下来我们看看它的具体实现类,通过封装一个 create 方法,来创建工厂对象,外部调用者就不需要关系工厂对象是如何创建的。再一个通过responseBodyConverter、requestBodyConverter 方法分别创建了请求响应和请求发起这两种产品的对象。

//这里就是创建了它的工厂对象
public static GsonConverterFactory create() {return create(new Gson());
}
//这里是通过封装了一个create方法传入一个Gson对象创建的工厂
public static GsonConverterFactory create(Gson gson) {if (gson == null) throw new NullPointerException("gson == null");return new GsonConverterFactory(gson);}@Overridepublic Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations,Retrofit retrofit) {TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type));return new GsonResponseBodyConverter<>(gson, adapter);}@Overridepublic Converter<?, RequestBody> requestBodyConverter(Type type,Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type));return new GsonRequestBodyConverter<>(gson, adapter);}

总结:工厂模式属于创建型的设计模式,主要设计的核心在创建我们的对象上面,使得创建对象和第三方调用者相隔离,这样对象的提供方和调用方的耦合关系就会减小。


http://chatgpt.dhexx.cn/article/81a97q56.shtml

相关文章

工厂设计模式有什么用?

工厂方法是非常古老且常用的设计模式。原因主要是一个系统要运转起来一定会涉及到对象的实例化过程&#xff0c;如果对象的实例化分散在各种逻辑代码之间&#xff0c;那么就会非常零乱、难以维护&#xff0c;bug自然也多。 工厂方法的出现解决的就是对象创建的问题&#xff0c…

Java中的工厂设计模式

引出工厂模式 package www.java.test;interface Computer{void printComputer(); } class MacbookPro implements Computer{Overridepublic void printComputer() {System.out.println("This is a MacbookPro");} } class SurfaceBook implements Computer{Override…

Java工厂设计模式

工厂设计模式 一、面向对象的设计原则1.1 OCP&#xff08;开闭原则&#xff0c;Open-Closed Principle&#xff09;1.2 DIP&#xff08;依赖倒转原则&#xff0c;Dependence Inversion Principle&#xff09;1.3 LOD&#xff08;迪米特法则&#xff0c;Law Of Demeter&#xff…

设计模式—工厂设计模式

工厂设计模式 1.概述2.简单工厂模式2.1 结构2.2 实现2.3 优缺点2.4 扩展 3.工厂方法模式3.1 概述3.2 结构3.3 实现3.4 优缺点 4.抽象工厂模式4.1 概述4.2 结构4.3 实现4.4 优缺点4.5 应用场景 5.扩展模式5.1 第一步&#xff1a;定义配置文件5.2 改写工厂类 6.JDK源码解析—Coll…

工厂设计模式 - 详解

介绍 工厂模式是Java中最常用的设计模式之一&#xff0c;这种类型的设计模式数据创建型模式。 主要就是负责创建对象的&#xff0c;当我们使用new创建对象的时候会导致对该对象的耦合性很严重&#xff0c;当我们需要修改的时候需要对所有new的对象进行修改&#xff0c;违反了软…

【iOS】—— 工厂设计模式

工厂设计模式 文章目录 工厂设计模式设计模式概念设计模式七大准则开闭原则单⼀职责原则里氏替换原则依赖倒转原则接口隔离原则迪米特法则合成复用原则 类族模式简单工厂模式优点缺点主要作用示例文件分类实现效果&#xff1a; 工厂方法模式优点缺点主要作用&#xff1a;示例&a…

【设计模式】工厂模式(Factory Pattern)

1. 概述 工厂模式&#xff08;Factory Pattern&#xff09;是最常用的设计模式之一&#xff0c;它属于创建类型的设计模式。它提供了一种创建对象的最佳方式&#xff0c;在工厂模式中&#xff0c;我们在创建对象时不会对客户端暴露创建逻辑&#xff0c;并且是通过一个共同的接…

设计模式之工厂模式,史上最强,不服来辩!

设计模式是对大家实际工作中写的各种代码进行高层次抽象的总结&#xff0c;如果设计模式没学会&#xff0c;抽象能力肯定就不会太强。常见的设计模式有 23 种&#xff0c;今天我们只聊最简单的工厂模式。 工厂模式是属于创建型模式的&#xff0c;通过工厂获取一个一个的新对象。…

工厂设计模式

1、概念 工厂模式分三种&#xff1a;简单工厂模式、工厂方法模式、抽象工厂模式 简单工厂模式(Simple Factory Pattern)&#xff1a;属于类的创新型模式&#xff0c;又叫静态工厂方法模式(Static FactoryMethod Pattern),是通过专门定义一个类来负责创建其他类的实例&#xf…

设计模式之工厂模式(factory pattern)

工厂顾名思义就是创建产品,根据产品是具体产品还是具体工厂可分为简单工厂模式和工厂方法模式,根据工厂的抽象程度可分为工厂方法模式和抽象工厂模式。该模式用于封装和管理对象的创建,是一种创建型模式。本文从一个具体的例子逐步深入分析,来体会三种工厂模式的应用场景和…

sqlserver2008的SSMS连接sqlserver2016的时候提示‘索引超出了数组界限。’

解决&#xff1a;打sp3补丁。 http://www.microsoft.com/en-us/download/details.aspx?id44271

Matlab报错 :“位置 x 处的索引超出数组边界”

经常遇到“位置 x 索引超出数组边界”的报错&#xff0c;今天突然想到一个以前一直没有太留意的奇葩问题&#xff1a;这个报错里“位置x”指的是哪里&#xff1f;为什么一会是“位置3”&#xff0c;一会是“位置1”&#xff0c;有什么神秘的规矩吗&#xff1f; 善用搜索没发现…

.net reflector 反编译失败 索引超出了数组界限问题处理方法

.net reflector 反编译失败 索引超出了数组界限问题处理方法 时间&#xff1a;9个月前 作者&#xff1a;庞顺龙 浏览&#xff1a;177 [站内原创&#xff0c;转载请注明出处] 标签&#xff1a; Reflector .net reflector 反编译失败 索引超出了数组界限问题处理方法 de…

matlab索引超出数组边界且不提示数组边界的一种处理办法

问题如下。 相关代码如下&#xff1a; 问题原因如下&#xff1a; 将excel表另存为txt时选择的保存类型是Unicode文本(*.txt)。 处理办法。 将Unicode文本(*.txt)换成文本文件&#xff08;制表符分隔&#xff09;(*.txt)。 问题的表现如下&#xff1a; 利用matlab工作区发现…

最短路径算法详细介绍

据 Drew 所知最短路经算法现在重要的应用有计算机网络路由算法&#xff0c;机器人探路&#xff0c;交通路线导航&#xff0c;人工智能&#xff0c;游戏设计等等。美国火星探测器核心的寻路算法就是采用的D*&#xff08;D Star&#xff09;算法。 最短路经计算分静态最短路计算和…

[算法]-最短路径算法总结

Dijkstra最短路径算法 按路径长度的递增次序&#xff0c;逐步产生最短路径的贪心算法 基本思想&#xff1a;首先求出长度最短的一条最短路径,再参照它求出长度次短的一条最短路径&#xff0c;依次类推&#xff0c;直到从顶点v 到其它各顶点的最短路径全部求出为止。 时间复杂…

c++实现最短路径算法(Dijkstra算法)

0简介 Dijkstra算法是一种计算某一顶点到其余顶点最短路径的算法。它采用了贪心的策略&#xff0c;实现时使用了广度优先。这个算法常学常忘&#xff0c;因此写篇博客彻底解决它。 1计算步骤介绍 Dijkstra的计算步骤不难&#xff0c;如下 (1)设置一个集合表示已经标记过的节…

最短路径算法——dijkstra

dijkstra 前提&#xff1a;在一张图里&#xff0c;不能有权值为负数的边。 给你一个出发点&#xff0c;求出发点到所有结点的最短距离是多少&#xff1f;如果无法到达某个点&#xff0c;则到这个点的距离是正无穷&#xff08;一般出现在有向图里面&#xff09;。 举个&#…

最短路径算法详解

前言&#xff1a; 最短路径算法&#xff1a;用于计算一个节点到其他所有节点的最短路径。主要特点是以起始点为中心向外层层扩展&#xff0c;直到扩展到终点为止。 例子&#xff1a; 暑期&#xff0c;你想要出门去旅游&#xff0c;但是在你出发之前&#xff0c;你想知道任意…

基于java最短路径算法的简单实现

一、我们先画一个可达路径图表&#xff1a; -1表示不可直达&#xff0c;0表示自己&#xff0c;其他整数表示长度或者权重 ABCDA012-1B-1015C-1-101D-1-1-10 用图形可表示为&#xff1a; 二、算法思路 1、先列出所有保存所有节点到可达节点的路径二维表 2、逐步寻找从起始节点到…