package list;
/*
* 定义一个常量字符串类,但是比String功能要少
*/
public final class MyString implements Comparable<MyString>, java.io.Serializable {
private final char[] value; // 字符串类都要有一个char数组用来存储字符集合
/*
* 构造方法,构造一个空串
*/
public MyString() {
this.value = new char[0];
}
/*
* 由字符串常量构造字符串,本质是对字符串的深拷贝,只是方法不一样罢了
*/
public MyString(java.lang.String str) {
this.value = new char[str.length()]; // 申请空间
for (int i = 0; i < this.value.length; i++) {
this.value[i] = str.charAt(i); // 进行赋值
}
}
/*
* 把字符串value中的从第i位(包括第i位)开始后n位构造字符串
*/
public MyString(char[] value, int i, int n) {
if (i >= 0 && n >= 0 && i + n < value.length) { // 容错处理
this.value = new char[n]; // 申请空间
for (int j = 0; j < n; j++)
this.value[j] = value[i + j]; // 赋值
} else
throw new StringIndexOutOfBoundsException("i=" + i + ",n=" + n + ",i+n=" + (i + n));
}
/*
* 这个方法本质上和第二个构造方法是一致的,同时也是上面的构造方法的一个特例
*/
public MyString(char[] value) {
this(value, 0, value.length);
}
/*
* 深拷贝构造方法,调用的是上面的方法
*/
public MyString(MyString str) {
this(str.value);
}
/*
* 返回串长度,即字符数组容量
*/
public int length() {
return this.value.length;
}
/*
* 形成字符串
*/
public String toString() {
return new String(this.value);
}
/*
* 查询第i位字符,并返回
*/
public char charAt(int i) {
if (i >= 0 && i < this.value.length)
return this.value[i];
throw new StringIndexOutOfBoundsException(i);
}
/*
* 求子串,有开始位置也有结束位置
*/
public MyString substring(int start, int end) {
if (start == 0 && end == this.value.length)
return this;
return new MyString(this.value, start, end - start);
// 最后要对应的是start之后的几位,所以用减号
}
/*
* 求子串方法重载,这个方法其实是是上一个方法的一个特例,所以直接调用上面方法
*/
public MyString substring(int begin) {
return substring(begin, this.value.length);
}
/*
* 连接串,将自身串与参数str连接在一起,其实本质就是在串后面再添加一个串str 和字符串类String中的+差不多,不过不如那个好理解
* 这里实现了深度拷贝,返回不再是之前那个串了,而是一个新的对象
*/
public MyString connect(MyString str) {
if (str == null)
str = new MyString("null");
char[] buffer = new char[this.value.length + str.length()];
int i;
for (i = 0; i < this.value.length; i++) // 复制当前串
buffer[i] = this.value[i];
for (int j = 0; j < str.value.length; j++) // 复制指定串str
buffer[i + j] = str.value[j];
return new MyString(buffer);
}
/*
* 比较串,如果同一位置出现不一样的,则返回差值 如果没有出现不一样的,则返回两者字符串的长度差
*/
public int compareTo(MyString str) {
for (int i = 0; i < this.value.length && i < str.value.length; i++)
if (this.value[i] != str.value[i])
return this.value[i] - str.value[i];
return this.value.length - str.value.length;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
}
}
1、串的定义
由n(n>=0)个字符串组成的有限序列,记为s= "S1S2.。。。。",其中s为串名,等号右面是串值,用双引号包起来,长度为0的串为空串,记为"",记住里面没有空格。
序号从0开始
2、子串
分为子串和真子串,其中子串的序号是指该孩子的首字符在主串中的序号,比如“dat”在“data”中的序号为0
3、串的比较(比较重要的)
串的比较规则与字符比较规则有关,字符比较规则由所属字符集的编码决定,通常在字符集中同一字母大大小写形式有不同的编码
两个串相等是指:串长度相同且各对应位置上的字符也相同
两个串的大小由对应位置的首个不同字符的大小(也就是编码方式的位置序列)决定,字符比较次序是从头开始依次想后,当两个串长度不等而对应位置的字符串都相同时,较长的串定义为较大(差值为长度差值)
4、String类设计特点:
(1)String类是最终类,不能被继承
(2)String类以常量串方式实现存储,声明字符数组是最终变量,串中各字符是只读的,只有当构造串对象时,对字符数组进行一次赋值,其后不能再次更改。
注意:String类只提供了charAt(i)取字符操作,不提供修改字符、插入串、删除子串操作。
详细地可以参考:Java中为什么String是不可变的
参考书籍:《数据结构(java版)》叶核亚,有不懂的,可以再看一下这本书