数据结构<十二>: 不可变的String实现

package com.mo.string;

/**
 *	根据串的抽象数据类型,应该有两种功能的串:
 *		一种要求是:任何对串的连接,插入子串和删除子串操作 都是 不改变原来串的值的
 *		另一种要求是: 任何对串的连接,插入子串和删除子串操作 都是 改变原来串的值
 *
 *	java中,String类是第一种功能的类,StringBuffer类是第二中功能的类
 *
 *	JDK的串类
 *		String类和StringBuffer类都是基于字符数组实现的,
 *		不同的是,String类的串一经创建,串的数值是无法改变的,即是一种状态不可变的对象
 *			而StringBuffer类的串创建后,串的值是可以改变的,因而StringBuffer类的对象的长度是可以改变的
 */
public class MyString {
	
	private char[] value;//字符数组
	private int count;//字符个数

	public MyString() {
		value = new char[0];
	}

	//对传进来的value字符数组分隔,取  value[offset] 到   value[offset+count]
	public MyString(char[] value,int offset,int count) {
		if(offset < 0) throw new StringIndexOutOfBoundsException();
		if(count > value.length - offset) throw new StringIndexOutOfBoundsException();
		if(count < 0) throw new StringIndexOutOfBoundsException();
		//创建一个空的字符数组
		this.value = new char[count];
		this.count = count;
		//将空的字符数组填满
		arrayCopy(value, offset, this.value, 0, count);
	}
	
	public MyString(char[] arr) {
		this.count = arr.length;
		//创建一个空的字符数组
		this.value = new char[count];
		//将参数传进来的arr,放到this.value中,因为这时候this.value还是空的
		arrayCopy(arr, 0, this.value, 0, count);
	}
	
	public MyString(String str) {
		char[] charArray = str.toCharArray();
		this.value = charArray;
		count = this.value.length;
	}
	
	/**
	 * 复制数组 
	 * @param src 原数组
	 * @param srcPos 从原数组的srcPos下标开始复制,复制length个长度
	 * @param dst 目标数组
	 * @param dstPos 从目标数组的dstPos下标开始接受原数组的元素,接受length个长度
	 * @param length 要复制原数组的长度
	 */
	static void arrayCopy(char[] src,int srcPos,char[] dst,int dstPos,int length) {
		//这里是防止数组越界
		if(src.length - srcPos < length && dst.length - dstPos < length) throw new StringIndexOutOfBoundsException();
		for(int i = 0;i < length;i++) { 
			dst[dstPos] = src[srcPos];
			srcPos++;
			dstPos++;
		}
	}
	
	//取字符
	public char charAt(int index) {
		if(index < 0 || index > this.value.length) throw new StringIndexOutOfBoundsException();
		return this.value[index];
	}
	
	//取串的长度
	public int length() {
		return count;
	}
	
	//取子串
	public MyString subString(int begin,int end) {
		if(begin < 0 || end < 0 || end < begin || end > this.value.length) throw new StringIndexOutOfBoundsException();
		return new MyString(value,begin,end - begin);
	}
	
	//取子串,从begin一直到结束
	public MyString subString(int begin) {
		return subString(begin, count);
	}
	
	//并接字符串
	public MyString concat(MyString str) {
		int length = str.length();
		char[] array = str.toArray();
		//创建一个空的字符数组
		char[] newchar = new char[(length+count)];
		//将字符数组填满
		arrayCopy(this.value, 0, newchar, 0, count);
		arrayCopy(array, 0, newchar, count, length);
		return new MyString(newchar);
	}

	//插进子串,新增加的字符串str从原来的字符串pos位置添加
	public MyString insert(MyString str,int pos) {
		if(pos < 0 || pos > count) throw new StringIndexOutOfBoundsException();
		if(pos != 0) {
			MyString s1 = this.subString(0, pos);
			MyString s2 = this.subString(pos);
			MyString c1 = s1.concat(str);
			MyString c2 = c1.concat(s2);
			return c2;
		}else {
			return this.concat(str);
		}
	}

	//删除子串
	public MyString delete(int begin,int end) {
		if(end < begin || begin < 0 || end > count ) throw new StringIndexOutOfBoundsException();
		if(begin == 0 && end == 0) {
			return new MyString();
		}else {
			MyString s1 = this.subString(0, begin);
			MyString s2 = this.subString(end);
			return s1.concat(s2);
		}
	}
	
	//打印字符串
	public void myPrint() {
		for(int i = 0; i < count; i++) {
			System.out.print(value[i]);
		}
		System.out.println();
	}
	
	public char[] toArray() {
		//创建一个空的字符数组
		char[] buf = new char[count];
		//经过这一步就把新建的字符数组填满了
		arrayCopy(this.value, 0,buf ,0, count);
		return buf;
	}
	
	public static void main(String[] args) {
		char[] s1 = {'a','b','c','d','e','g'};
		char[] s2 = {'a','b','c','d','e','g','a','b','c','d','g','a','b','g','a','b'};
		
		MyString m1 = new MyString();
		m1.myPrint();

		MyString m2 = new MyString(s1);
		m2.myPrint();
		
		System.out.println("-------------");
	
		MyString m3 = new MyString(s2, 2, 7);
		m3.myPrint();
		System.out.println(m3.charAt(2));
		System.out.println(m3.length());
		System.out.println("end");

		System.out.println("-------------");
		
		MyString m4 = new MyString(s2);
		m4.myPrint();
		m4.subString((m4.length() - 3)).myPrint();
		
		m4.subString(0, 3).myPrint();
		
		System.out.println("------------------");
		
		MyString m5 = m4.subString(m4.length() - 3);
		MyString m6 = m4.subString(m4.length() - 4);
		m5.myPrint();
		m6.myPrint();
		MyString m7 = m5.insert(m6, 1);
		m7.delete(1, 3).myPrint();
	}
	
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值