String 类的解析

本文介绍了Java中String类的重要性质,它是一个不可继承的类,实现了Serializable、Comparable和CharSequence接口。String对象存储在堆内存中,提供了如length()、equals()、compareTo()、startsWith()、endsWith()、contains()等丰富的操作字符串的方法。此外,还概述了部分方法的实现思路。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在编程过程中,我们都会用到String定义的字符串,但是String在Java定义中是一个被final修饰即该String类不能够被继承,但是String类继承了三个接口:Serializable接口(该String类的对象可以进行序列化(将内存中的数据移交到硬盘上的一个过程))、Comparable接口(该String类的对象可以进行大小的比较)、CharSequence接口(该String类本质上是一个字符序列),所以和我们定义的整型变量、double类型的变量是不一样的,String定义的变量是一个对象,数据存储的位置是在堆内存中,而我们定义的像整型这样的变量它存储的位置是在方法区中的堆内存中的。下面是一些String类型的常用方法以及部分方法是实现(虽然和源码有差别,但是提供思路是一样的)
常用方法:
               int length()       获取字符串的长度
               boolean isEmpty()         判断字符串是否为空
               char charAt(int index)          返回index处的字符
               boolean equals(Object anObject)           比较字符串的内容
               boolean equalsIgnoreCase(String anotherString)                忽略大小写比较
               int compareTo(String anotherString)                         按字典顺序比较两个字符串
               int compareToIgnoreCase(String str)                        按字典顺序忽略字母大小写比较两个字符串
               boolean startsWith(String prefix)                     是否以指定的某个字符串开头
               boolean startsWith(String prefix, int toffset)          从该字符串的某个位置开始是否以某个指定的字符串开头
               boolean endsWith(String suffix)                       是否以指定的某个字符串结尾
               boolean contains(CharSequence s)                  是否包含某个字符串
               int indexOf(int ch, int fromIndex)                        从指定的某个位置开始 从左到右求ch第一次出现的角标
               int lastIndexOf(int ch)                         求ch最后一次出现的角标
              String substring(int beginIndex, int endIndex)         截取字符串的某个子串 
              String concat(String str)                           将某个字符串连接在该字符串之后
              String replace(char oldChar, char newChar)                   将字符串中某个字符进行替换
              String toLowerCase()                               将字符串中的所有的大写字母转成小写
              String toUpperCase()                               将字符串中的所有的小写字母转成大写
              String trim()                                              取出两边的空格

部分函数实现:



import java.util.Arrays;
import java.lang.StringIndexOutOfBoundsException;

public final class MyString{
    private char[] value;    //String类中的字符串是由字符数组组成的,所以唯一较为重要的属性为字符数组
    
    MyString(){    //构造函数为空字符数组
        this.value=new char[0];
    }
    
    MyString(char[] value){   //代参的构造函数传进来的参数是一个字符数组
         this.value=Arrays.copyOf(value,value.length);   //调用Arrays工具栏的方法对传进来的数组进行复制
    }
    
    public int length(){   //返回字符串的长度
        return value.length;
    }
    
    public boolean isEmpty(){   //判断字符串是否为空
        return value.length==0;
    }
    
    public char charAt(int index){  //返回字符串相应位置的字符
        if(index<0||index>=value.length){
            throw new StringIndexOutOfBoundsException();
        }
        return value[index];
    }
    
    public boolean equals(MyString anothermyString) {  //判断两个字符串是否相等
    	if(this == anothermyString) {    //先判断当前对象与传进来的对象是否是同一个
    		return true;
    	}
    	else{  
            int n = this.value.length; //当前对象的长度
            if (n == anothermyString.value.length) {  //如果两个长度相等,再去逐个判断字符的内容
                char v1[] = value; 
                char v2[] = anothermyString.value;  //将两个字符串分别转化为字符数组
                int i = 0;  //从角标0开始比
                while (n-- != 0) { 
                    if (v1[i] != v2[i]) //只要有一个字符不同,两个字符串就是不想等的
                        return false;
                    i++;
                }
                return true;
            }
        }
        return false;
    }
    
    public boolean equalsIgnoreCase(MyString another){  //忽略两个字符串的大小写比较内容是否相等
        if(another==null){
            return false;
        }
        if(this==another){
            return true;
        }
        int len1=this.value.length;
        int len2=another.value.length;
        if(len1==len2){
            char[] c1=value;
            char[] c2=another.value;
            int i=0;
            while(i<len1){
                char ch1=c1[i];
                char ch2=c2[i];
                if(Character.isLetter(ch1)&&Character.isLetter(ch2)){  //在这里做特殊处理,如果是字母就要都转化成大写字母,
                    ch1=ch1>=97?(char)(ch1-32):ch1;
                    ch2=ch2>=97?(char)(ch2-32):ch2;
                }
                if(ch1!=ch2){  //然后再判断两个字符是否是相等,如果不是字母则直接判断两个字符是否相等的
                    return false;
                }
                i++;
            }
            return true;
        }else{
            return false;
        }
    }

	 public int compareTo(MyString anotherString) {  //按字典顺序比较两个字符串
		   if(this == anotherString) {
			   return 0;
		   }else {
		    int len1 = value.length;
	        int len2 = anotherString.value.length;
	        int lim = Math.min(len1, len2);
	        char[] v1 = value;
	        char[]  v2 = anotherString.value;

	        int k = 0;
	        while (k < lim) {
	            char c1 = v1[k];
	            char c2 = v2[k];
	            if (c1 != c2) {   //如果两个字符串有不一样的字符
	                return c1 - c2;   //直接相减获取大小
	            }
	            k++;
	        }
	        return len1 - len2;   //如果一个字符串是另一个字符串的子串,直接返回长度差值
		  }
	 }
    
	public int compareToIgnoreCase(MyString str) {  //按字典顺序忽略字母大小比较两个字符串
		 if(str == null) {
			 return value.length;
		 }
		 if(str == this) {
			 return 0;
		 }
		int len1 = value.length;
        int len2 = str.value.length;
        int lim = Math.min(len1, len2);
        char v1[] = value;
        char v2[] = str.value;
        int k = 0;
        while (k < lim) {
            char c1 = v1[k];
            char c2 = v2[k];
            if(Character.isLetter(c1)&&Character.isLetter(c2)) {//在这里做特殊处理,如果是字母的话要先将其都转化为大写
            	c1 = c1>=97?(char)(c1-32):c1;
            	c2 = c2>=97?(char)(c2-32):c2;
            	if(c1!=c2) {  //不相等直接获取两个字符的差值
            		 return c1 - c2;   //直接相减获取大小
            	}
            }
            if (c1 != c2) {   //如果两个字符串有不一样的字符
                return c1 - c2;   //直接相减获取大小
            }
            k++;
        }
        return len1 - len2;   //如果一个字符串是另一个字符串的子串,直接返回长度差值
     }
	 
	public boolean startsWith(MyString prefix) {  //判断某字符串是不是以某指定的字符串开头
		if(prefix == null) {
			return false;
		}
		if(prefix == this) {
			return true;
		}
		int len1 = this.value.length;
		int len2 = prefix.value.length;
		if(len2>len1) {          //如果指定开头的字符串的长度比要判断的字符串长度大,则明显不是
			return false; 
		}
		char[] v1 = value;  //如果是常规的情况,就逐一比较
		char[] v2 = prefix.value;
		int i=0;
		while(i<len2) {
			if(v1[i]!=v2[i]) {
				return false;
			}
			i++;
		}
		return true;
	}

	public boolean startsWith(MyString prefix, int toffset) {  //判断某字符串从某位开始是不是以指定的字符串开始
		    char ta[] = value;
	        int to = toffset;
	        char pa[] = prefix.value;
	        int i = 0;
	        int pc = prefix.value.length;
	        if ((toffset < 0) || (toffset > (value.length - pc))) {  //特殊一,判断的位置必须是在该数组里面
	            return false;
	        }
	        while (i<pc) {
	            if (ta[to++] != pa[i++]) {  //特殊二,从指定位置开始判断,不从数组其实位置开始
	                return false;
	            }
	            i++;
	        }
	        return true;
	}
	
	public boolean endsWith(MyString suffix) { //判断字符串是不是以指定的某字符串结尾
		return startsWith(suffix, value.length - suffix.value.length);
	}
	
	
	public boolean contains(MyString s) {  //某字符串是不是包含字符串
		if(s==null) {
			return false;
		}
		if(s==this) {
			return true;
		}
		int len1 = value.length;
		int len2 = s.value.length;
		char[] v1 = value;
		char[] v2 = s.value;
		if(len2>len1) {
			return false;
		}else {
			for(int i =0;i<len1-len2+1;i++) {
				MyString sub = substring(i,len2);//截取子串,类似于滑动窗口
				if(sub.equals(s)) {
					return true;
				}
			}
			return false;
		}
		
	}
	
	public int indexOf(int ch, int fromIndex) {  //从指定的位置开始 从左到右ch第一次出现的角标
	
		char[] c= value;
		if(fromIndex <0 || fromIndex>=value.length) {
			return -1;
		}
		for(int i = fromIndex; i<value.length;i++) {
			if(c[i]==ch) {
				return i;
			}
		}
		return -1;
	}
	
	public int lastIndexOf(int ch) {    //找出该字符串的最后出现的下标
		char[] c= value;
		for(int i = value.length-1; i>=0;i--) {
			if(c[i]==ch) {
				return i;
			}
		}
		return -1;
	}
	
	public MyString substring(int beginIndex,int endIndex) {   //取出从哪儿到哪儿的子串
		if(beginIndex>=endIndex) {
			return null;
		}
		if(beginIndex<0 || endIndex>value.length) {
			return null;
		}
		char[] c =new char[endIndex-beginIndex];
		char[]  v1 = value;
		int index =0;
		for(int i =beginIndex;i<endIndex;i++) {
			c[index++]=v1[i];
		}
		MyString s = new MyString(c);
		return s;
	}
	
	public MyString concat(MyString str){  //是否包含某字符串
        if(str==null){
            return this;
        }
        char[] c=new char[length()+str.length()];
        for(int i=0;i<length();i++){
            c[i]=value[i];
        }
        for(int i=0;i<str.length();i++){
            c[i+length()]=str.value[i];
        }
        return new MyString(c);
    }
	
	public MyString replace(char oldChar, char newChar){  //将新的字符串取代旧的字符串
        char[] c=Arrays.copyOf(value,value.length);
        for(int i=0;i<c.length;i++){
            if(c[i]==oldChar){
                c[i]=newChar;
            }
        }
        return new MyString(c); //这里返回的是一个新的数组
    }
	
	
    public MyString trim(){  //去掉两边的空格,双指针法
        int i=0;
        int j=length()-1;
        while(value[i]==' '){
            i++;
        }
        while(value[j]==' '){
            j--;
        }
        return substring(i,j+1);
    }
    
	public String toString(){
        String s="";
        for(int i=0;i<value.length;i++){
            s+=value[i];
        }
        return s;
    }
	
	public MyString toLowerCase(MyString str) {//将该字符串中所有大写字母转小写
		if(str==null) {
			return null;
		}else {
		int n = str.value.length;
		char s[] = str.value;
		for(int i =0;i<n;i++) {
			char s1 = s[i];
			if(Character.isLetter(s1)) {
				s[i]=s1<=90?(char)(s1+32):s1;
			}
		}
		MyString ms = new MyString(s);
		return ms;
		}
	}
	
	public MyString toUpperCase(MyString str) {//将该字符串中所有小写字母转大写
		int n = str.value.length;
		char s[] = str.value;
		for(int i =0;i<n;i++) {
			char s1 = s[i];
			if(Character.isLetter(s1)) {
				s[i]=s1>=97?(char)(s1-32):s1;
			}
		}
		MyString ms = new MyString(s);
		
		return ms;
	}
	
	
	 
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值