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版)》叶核亚,有不懂的,可以再看一下这本书