java-String字符串的常用使用方法

原码

首先有个String类,看看原码(看源码的方式,我用eclipse为例。鼠标放到String上,点击Alt键,然后变成一个手的样子,再点一下,就到了String.class里面可以看原码了
在这里插入图片描述
特点

  1. String类是一个最终类。
  2. 属性有一个private final 的char型数组,这个数组是存我们写的字符串的值

String 是引用类型

		String s1 = "123";//给一个字符串赋值
		s1 = "abc" ; //修改字符串中的值
		System.out.println(s1); //输出看看,字符串的值改变了。

前面图片说了字符串类里面不能修改字符串的值,但是为什么这里可以修改字符串的值。
一开始我很不理解,因为字符串是引用类型,应该来说例子中的s1保存的是"123"这个值的地址,不应该被改变,但是为什么这里可以给对象s1修改值呢,原因是当你修改地址中的值(例如上面的"abc")的时候,那么也即是在内存中再开辟一个空间保存"abc",那么对象s1中保存的地址也发生了变化,变成了"abc"这个值的地址。
上结论
String类型创建对象后,里面的value数组值不能改变,但是String字符串的指向是可以改变的
过程就是我上面的,不知道是我学懵了,还是砸了。

	//这个代码看起来就比较清晰,和上面的简化版是一样的,也就是解释这个过程
		String s1 = new String("123");
		s1 = new String("abc") ;
		System.out.println(s1);

在这里插入图片描述

字符串,如果直接赋值,相当于在常量池中创建一个对象,下次再赋值时,如果是同一个值,直接引用,是同一个地址
直接赋值:代码如下

String s1 = "123";//给一个字符串赋值

常量池,前面我有写过final修饰的类,方法,属性呀,修饰属性那么这个属性就是常量,定义时就要赋初值,不能再赋值,即为常量。常量池那么也就是很多很多的常量放在一起构成一个池,池的作用就是不用创建对象,减少对内存的占用。

如果此时代码,变成这样

		String s1 = "123";
		String s2 = "123" ;
		//String是一个引用类型,应该来说,值相等,不一定地址相等,但是因为是直接赋值,那么就是常量池里创建对象,值相同,就是同一个对象。
		System.out.println(s1 == s2);

结果为:
在这里插入图片描述在这里插入图片描述

通过new赋值,相当于创建的一个对象,多次使用,就创建了多个对象
也就是说 ,new创建对象,就不是在常量池里创建对象,地址也就不同。

		String s1 = new String("123");
		String s2 = new String("123") ;
		System.out.println(s1 == s2); //比较地址
		System.out.println(s1.equals(s2)); //比较值

在这里插入图片描述

再来看看直接赋值的

扫描二维码关注公众号,回复: 12330265 查看本文章
		String s3 = "12";
		String s4 = "12" ;
		System.out.println(s3 == s4);
		System.out.println(s3.equals(s4));

在这里插入图片描述

说明字符串对象通过new创建的,如果他们的值相等,使用 ==判断和equals得到的结果是不一样的
字符串直接赋值的,= =和equals结果是一样的。这里面的原理,我一会还说不清楚。所以为了避免出错,字符串比较值是否相等,就用equals()进行判断

字符串难以理解的一个点

字符串作为一个引用类型,也就是字符串对象保存的应该是一个地址,但是下面这个例子却打破了这个常识。

public class Test {
    
    
	public static void main(String []args) {
    
    
		
		String s1 = "123456789";
		String s2 = "123456789";
		System.out.println(s1 == s2);
		System.out.println(s1.equals(s2));
		
		func(s1); //这行报错
		System.out.println(s1 );

	} 
	public  void func( String s) {
    
    
		s = "1" ;
	}
}

在这里插入图片描述
看看结果
在这里插入图片描述
这个就要说到保存string的char型数组是private final修饰的,private修饰说明不能在外部修改,final表示常量,也是不能修改的意思。这个说明在字符串赋值过后就不能对字符串进行修改,但是可以改变字符串的地址从而改变字符串的值。还是验证了下面这句话。

String类型创建对象后,里面的value数组值不能改变,但是String字符串的指向是可以改变的

字符串和数组还是很不一样

是否在常量池中创建,就看 =右边是不是只是常量,不能改变。

		String s1 = "1"; //常量池中创建
		String s2 = s1 + "2" ; //只要右边是常量那么就不会改变,s2会自动变成"12"
		String s3 = s1 + "2" ; //由于s1这个值可能发生改变,也就是保存的地址可能改变,所以s3也就不会进入内存池里,

看看下面的

		final String s4 = "1" ; //说明s4已经是常量了,final修饰嘛,常量池中创建
		String s5 = s4 + "2" ; //右边是常量,所以s5在常量池中识别为"12"

再看看下面的
先看看String类里面有个字符串拼接的方法concat。上源码

public String concat(String str) {
    
    //传进来的参数str是拼接上的字符串,举例说明的话,就是String s2 = s1 + "2" ;str就相当于“2”
        int otherLen = str.length();
        if (otherLen == 0) {
    
    
            return this; //如果拼接的字符串长度为0,空串,那么直接返回当前对象。
        }
        int len = value.length;
        char buf[] = Arrays.copyOf(value, len + otherLen);
        str.getChars(buf, len);
        return new String(buf, true); //长度不会0,返回一个新的对象,有new嘛
    }
String s6 = "1".concat("2"); //这个是new一个对象的,因为拼接“2”呀,有长度,不在常量池里
String s6 = "12".concat(""); //这个就直接返回了,因为拼接空串嘛,还是在常量池里

charAt(index)

	**作用就是传进去一个下标,返回查询字符串中下标的某个字符**
public char charAt(int index) {
    
    //index是下标
        if ((index < 0) || (index >= value.length)) {
    
    //越界就抛出异常
            throw new StringIndexOutOfBoundsException(index);
        }
        return value[index]; //没有越界,就返回下标
    }
		String s7 = "123456789";
		char c = s7.charAt(8);
		System.out.println(c );

在这里插入图片描述
说明下标8的值为9

contains(“string”)

		boolean res = s7.contains("123"); //判断某个字符串包含某个字符串,返回一个boolean值。这个就是s7这个串是否包含"123"这个串。
		System.out.println(res );

在这里插入图片描述

trim()

去掉字符串两边的空格,但是不能去掉字符串中间任何位子的空格

		String s7 = "  123456 789 ";
		String s8 = s7.trim(); 
		System.out.println(s8 );

在这里插入图片描述

toCharArray()

变成字符型数组,这样就有下标了

		String s7 = "  123456 789 ";
		char [] c1 = s7.toCharArray();
		for(int i = 0 ; i < c1.length ; i++ ) {
    
    
			System.out.println(c1[i]);
		}

在这里插入图片描述

replace(“旧串” , “新串”)

将字符串中某个串换成新串

		String s7 = "  123456 789 ";
		String str1 = s7.replace("123", "abc"); //将“123”替换“abc”
		System.out.println(str1);

在这里插入图片描述

substring(startIndex , endIndex)

切割字符串,可以没有endIndex结尾下标,startIndex开始下标一定要有。

		String s7 = "123456789";
		String res2 = s7.substring(5);
		System.out.println(res2);
		String res3 = s7.substring(3 , 7);
		System.out.println(res3);

在这里插入图片描述

spilt(“串”)

按照串分割,得到字符串数组。切了那么那一部分就没有了

		String s7 = "123456789";
		String [] res4 = s7.split("45" );
		for(int i = 0 ; i < res4.length ; i++) {
    
    
			System.out.println(res4[i]);
		}

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/toomemetoo/article/details/112509750
今日推荐