🐨 编写泛型
type
status
date
slug
summary
tags
category
icon
password
Property
 
通常来说,泛型类一般用在集合类中,例如ArrayList<T>,我们很少需要编写泛型类。
如果确实需要编写一个泛型类,那么,应该如何编写它?
可以按照以下步骤来编写一个泛型类。
首先,按照某种类型,例如:String,来编写类:
然后,标记所有的特定类型,这里是String
最后,把特定类型String替换为T,并申明<T>
 
 

静态方法

🐨 擦拭法
type
status
date
slug
summary
tags
category
icon
password
Property
 
泛型是一种类似”模板代码“的技术,不同语言的泛型实现方式不一定相同。
Java语言的泛型实现方式是擦拭法(Type Erasure)。
所谓擦拭法是指,虚拟机对泛型其实一无所知,所有的工作都是编译器做的。
例如编写了一个泛型类Pair<T>,这是编译器看到的代码:
而虚拟机根本不知道泛型。这是虚拟机执行的代码:
因此,Java使用擦拭法实现泛型,导致了:
  • 编译器把类型<T>视为Object
  • 编译器根据<T>实现安全的强制转型。
使用泛型的时候,我们编写的代码也是编译器看到的代码:
🐨 extends通配符
type
status
date
slug
summary
tags
category
icon
password
Property
 
Pair<Integer>不是Pair<Number>的子类。
假设我们定义了Pair<T>
然后又针对Pair<Number>类型写了一个静态方法,它接收的参数类型是Pair<Number>
上述代码是可以正常编译的。使用的时候,传入:
注意:传入的类型是Pair<Number>,实际参数类型是(Integer, Integer)
既然实际参数是Integer类型,试试传入Pair<Integer>
编译错误,原因很明显,因为Pair<Integer>不是Pair<Number>的子类,因此,add(Pair<Number>)不接受参数类型Pair<Integer>
🐨 super通配符
type
status
date
slug
summary
tags
category
icon
password
Property
 
泛型的继承关系:Pair<Integer>不是Pair<Number>的子类
考察下面的set方法:
传入Pair<Integer>是允许的,但是传入Pair<Number>是不允许的。
extends通配符相反,这次希望接受Pair<Integer>类型,以及Pair<Number>Pair<Object>,因为NumberObjectInteger的父类,setFirst(Number)setFirst(Object)实际上允许接受Integer类型。
使用super通配符来改写这个方法:
注意到Pair<? super Integer>表示,方法参数接受所有泛型类型为IntegerInteger父类的Pair类型。
下面的代码可以被正常编译:
 
🐨 泛型和反射
type
status
date
slug
summary
tags
category
icon
password
Property
 
Java的部分反射API也是泛型。例如:Class<T>就是泛型:
调用ClassgetSuperclass()方法返回的Class类型是Class<? super T>
构造方法Constructor<T>也是泛型:
可以声明带泛型的数组,但不能用new操作符创建带泛型的数组:
必须通过强制转型实现带泛型的数组:
使用泛型数组要特别小心,因为数组实际上在运行期没有泛型,编译器可以强制检查变量ps,因为它的类型是泛型数组。但是,编译器不会检查变量arr,因为它不是泛型数组。因为这两个变量实际上指向同一个数组,所以,操作arr可能导致从ps获取元素时报错,例如,以下代码演示了不安全地使用带泛型的数组:
🐼 集合
type
status
date
slug
summary
tags
category
icon
password
Property
 
集合就是“由若干个确定的元素所构成的整体”。
在数学中,我们经常遇到集合的概念。例如:
  • 有限集合:
    • 一个班所有的同学构成的集合;
    • 一个网站所有的商品构成的集合;
    • ...
  • 无限集合:
    • 全体自然数集合:1,2,3,……
    • 有理数集合;
    • 实数集合;
    • ...
🐼 List
type
status
date
slug
summary
tags
category
icon
password
Property
 
 
在集合类中,List是最基础的一种集合:它是一种有序列表。
List的行为和数组几乎完全相同:List内部按照放入元素的先后顺序存放,每个元素都可以通过索引确定自己的位置,List的索引和数组一样,从0开始。
数组和List类似,也是有序结构,如果使用数组,在添加和删除元素的时候,会非常不方便。例如,从一个已有的数组{'A', 'B', 'C', 'D', 'E'}中删除索引为2的元素:
notion image
这个“删除”操作实际上是把'C'后面的元素依次往前挪一个位置,而“添加”操作实际上是把指定位置以后的元素都依次向后挪一个位置,腾出来的位置给新加的元素。这两种操作,用数组实现非常麻烦。
 
因此,在实际应用中,需要增删元素的有序列表,使用最多的是ArrayList。实际上,ArrayList在内部使用了数组来存储所有元素。例如,一个ArrayList拥有5个元素,实际数组大小为6(即有一个空位):
notion image
当添加一个元素并指定索引到ArrayList时,ArrayList自动移动需要移动的元素:
notion image
🦥 InputStream和OutputStream
type
status
date
slug
summary
tags
category
icon
password
Property
 
 

InputStream

InputStream就是Java标准库提供的最基本的输入流,位于java.io这个包里。java.io包提供了所有同步IO的功能。
要特别注意的一点是,InputStream并不是一个接口,而是一个抽象类,它是所有输入流的超类。这个抽象类定义的一个最重要的方法就是int read(),签名如下:
这个方法会读取输入流的下一个字节,并返回字节表示的int值(0~255)。如果已读到末尾,返回-1表示不能继续读取了。
 
FileInputStreamInputStream的一个子类。顾名思义,FileInputStream就是从文件流中读取数据。
完整地读取一个FileInputStream的所有字节:
在计算机中,类似文件、网络端口这些资源,都是由操作系统统一管理的。应用程序在运行的过程中,如果打开了一个文件进行读写,完成后要及时地关闭,以便让操作系统把资源释放掉,否则,应用程序占用的资源会越来越多,不但白白占用内存,还会影响其他应用程序的运行。
GUI
type
status
date
slug
summary
tags
category
icon
password
Property
 
图表可视化
type
status
date
slug
summary
tags
category
icon
password
Property

图线的绘制与装饰

使用plot()函数绘制图线

在MATLAB中,使用plot()函数绘制图线:
各参数意义如下:
  • x: 图线上点的x坐标
  • y: 图线上点的y坐标
  • LineSpec: 图线的线条设定,三个指定线型标记符号颜色设定符组成一个字符串,设定符不区分先后
线性方程式与线性系统
type
status
date
slug
summary
tags
category
icon
password
Property

线性方程式表示

示例1

解方程组:
notion image
把方程组转换为矩阵表示,再求解
notion image

示例2

notion image
数字图像处理
type
status
date
slug
summary
tags
category
icon
password
Property

图像的读取和展示

MATLAB能够处理的数字图像分为三种:二值图像灰度图像彩色图像.
notion image
  • 二值图像在MATLAB中以一个矩阵存储,矩阵中元素的取值为0(表示白)或1(表示黑).
    • notion image
  • 灰度图像在MATLAB中以一个矩阵存储,矩阵中元素的取值介于0~255之间,表示灰度.
    • notion image
  • 彩色图像在MATLAB中以三个矩阵存储,每个矩阵中元素的取值介于0~255之间,分别表示颜色R,G,B分量的浓度