Java | String(2)


在笔试面试的算法题中,String是重要考点,在实际项目中,字符串也是十分常用的数据类型,因此要熟练掌握对String的运用。

使用

初识

如下代码:

  • str是一个字符串常量,与C/C++不同的是,Java并没有规定字符串末尾要包含’\0’。
  • String重写了toString方法,因此其输出的不是str的地址,而是str字符串的内容。
String str = "hello";
System.out.println(str);

常见new创建String方式

  • 每次new一个对象的时候,都会在堆区申请一段空间。
//创建一个空的
String str1 = new String();
System.out.println(str2);// 输出为空
//创建一个指定字符串的
String str2 = new String("head");
System.out.println(str3);// 输出为head
//创建一个由字符数组指定字符串的
char[] array = {'h','e','a','d'};
String str4 = new String(array);
//指定需要字符数组中的哪些字符
System.out.println(str4);// 输出为head
String str5 = new String(array,1,2);// 第二个参数为偏移量,第三个参数为字符的数量
System.out.println(str5);// 输出为ea

“”(空)和null

  • str6的意思为str6指向了一个对象,但里面的字符为空,因此可以正常调用String的方法
  • str7的意思为不指向任何对象,对空指针执行方法调用时会报错
String str6 = ""; //指向的对象为空(里面的字符为空)
String str7 = null;//不指向任何对象
System.out.println(str6.length());  // 0
System.out.println(str6.isEmpty()); // true
System.out.println(str7.length()); // 报错
System.out.println(str7.isEmpty());// 报错

补充:字符串常量可以直接调用String的方法,如下所示

System.out.println("hello".length());
//结果为5

查找

char charAt(int index);

  • 返回index位置上字符,如果index为负数或者越界,抛出IndexOutOfBoundsException异常。

int indexOf();

String str = "hello,iamhead";
int ret = str.indexOf('i');
System.out.println(ret); // 6
int ret2 = str.indexOf('i',3);//从指定位置开始查找
System.out.println(ret2); // 6

int ret3 = str.indexOf("am");
System.out.println(ret3); // 7
int ret4 = str.indexOf("am",2);//从指定位置开始查找
System.out.println(ret4); // 7

int lastIndexOf();

倘若逆序查找时还指定了位置,是指从顺序(从左到右)指定位置后,从指定位置逆序(从右向左)进行查询,获取到的位置是顺序(从左到右)得到的,而非逆序!!

String str = "hello,iamhead";
int ret = str.lastIndexOf('i');
System.out.println(ret); // 6
int ret2 = str.lastIndexOf('i',3);//从指定位置开始向前查找
System.out.println(ret2); // -1

int ret3 = str.lastIndexOf("am");
System.out.println(ret3); // 7
int ret4 = str.lastIndexOf("am",11);//从指定位置开始向前查找
System.out.println(ret4); // 7

比较

== —> 等号

对于八大基本数据类型,== 比较的是变量中的值,对于引用数据类型,== 比较的是引用中的地址,即是否引用了同一对象
注:Java八大基本数据类型分别为byte、short、int、long、float、double、boolean、char,除此之外的数据均为引用数据类型,如本文的String。

int a = 10;
int b = 20;
int c = 10;
// 对于基本类型变量,==比较两个变量中存储的值是否相同 
System.out.println(a == b); // false 
System.out.println(a == c); // true
// 对于引用类型变量,==比较两个引用变量引用的是否为同一个对象 
String s1 = new String("hello"); 
String s2 = new String("hello"); 
String s3 = new String("world"); 
String s4 = s1; 
System.out.println(s1 == s2); // false,因为比较的是地址 
System.out.println(s2 == s3); // false,地址和值都不相同 
System.out.println(s1 == s4); // true,因为地址相同

== 比较的返回类型为boolean,不是false就是true。

equals —> boolean equals(Object object);

已知Object是所有类的超类,其中包含了euqals方法,而String类重写了equals方法,因此若要比较两个字符串的值是否相等,就使用equals方法。String中的equals基于以下规则:

  1. 先检测要比较的两个对象是否为同一个对象,如果是则直接返回true,如果不是则返回。
  2. 检测object是否为String类型的对象,如果是则继续比较,如果不是则返回false。
  3. this和object两个字符串的长度是否相同,是继续比较,否则返回false。
  4. 按照字典序,从前往后逐个字符进行比较。
// 示例代码如下,即为String对equals的重写
public boolean equals(Object object) { 
	if (this == object) { 
		return true; 
	}
	if (object instanceof String) { 
		// 将anObject向下转型为String类型对象 
		String anotherString = (String)object; 
		int n = value.length;
		if (n == anotherString.value.length) { 
			char v1[] = value; 
			char v2[] = anotherString.value; 
			int i = 0;
		}
		while (n-- != 0) { 
			if (v1[i] != v2[i]) return false;
				i++; 
		} 
				return true; 
	} 
}
return false;

重要面试题:==和equals都是干嘛的,异同?
Java | “==”和 equals() 的异同

int compareTo(String s)

  • 将s1和s2两个字符串按照字典序进行比较,如果s1大于s2,则返回正数,如果s1小于s2,返回负数,等于返回0。
String s1 = new String("hello");  
String s2 = new String("hello");
System.out.println(s1.compareTo(s2)); //返回 0 

int compareToIgnoreCase(String s)

  • 使用办法同上,唯一的区别是忽略了大小写。

转换

数值转字符串

String.valueOf()可以将许多对象转换为String。
![[Pasted image 20240624235837.png]]

String s = String.valueOf(19.9);
System.out.println(s);

字符串转数字

int data1 = Integer.parseInt("198");  
double data2 = Double.parseDouble("19.9");

大小写转换

String str7 = "hello";  
String str8 = str7.toUpperCase(); 
String str9 = str8.toLowerCase();
//注:不是在原有的基础上进行转化,而是转换后变成新的对象,因为Java中String不可修改

字符串转数组、数组转字符串

//字符串转数组  
String str1 = "hello";  
char[] array1 = str1.toCharArray();  
//数组转字符串  
char[] array2 = {'a','b','c'};  
String str2 = new String(array3);

替换

replace()、replaceAll()

  • replace()既支持字符的替换,也支持字符串的替换。
  • replaceAll()仅支持字符串的替换,但是它还支持给予规则表达式的替换,如replaceAll(“\d”, “*”)把一个字符串所有的数字字符都换成星号。
  • 因为字符串是不可变对象,所以字符串一经创建就无法改变了。因此替换时并==不是在原有字符串上进行替换==,而是产生出一个新的字符串。
String str = "hello,iamhellohello";
String ret1 = str.replace("hello","head");// str.replaceAll("hello","head");
System.out.println(ret1); // head,iamheadhead
String ret2 = str.replace('h','a');
System.out.println(ret2); // aead,iamaeadaead
//规则表达式的替换
String str2 = "1head2head3head";
String ret3 = str2.replaceAll("\\d","*");
System.out.println(ret3); // *head*head*head

replaceFirst()

  • 仅对第一个匹配的字符串进行替换,随后结束,使用可以参考replace(),但是不支持单个字符的替换(其实写成replaceFirst(“x”,“y”)类似的样子就行了,没有必要纠结于替换单个字符嘞)。

拆分

  • String[] split(String regex) :将字符串全部拆分。
  • String[] split(String regex, int limit):将字符串以指定的格式拆为limt组。
String str = "hello head world";  
String[] ret = str.split(" ");//以空格进行拆分:[hello,head,world]
String[] ret2 = str.split(" ", 2);//分为两组 : [hello,head world]

截取

  • String substring(int beginIndex):从指定索引截取到结尾
  • String substring(int beginIndex, int endIndex):截取部分内容,注意前闭后开
String str = "abcdefg";
String ret = str.substring(0,3); // abc 注意左闭右开
String ret2 = str.substring(3);  // defg

StringBuilder和StringBuffer

比较

  • 由于String的不可更改特性,为了方便字符串的修改(主要是为了加快修改的时间效率),Java中又提供StringBuilder和StringBuffer类。

  • 和 String 类不同的是,StringBuffer和StringBuilder类的对象能够被多次的修改,并且不会产生新的对象。

  • 这两个类大部分功能是相同的,但是StringBuilder是线程不安全的,它的方法不安全,不能够同步访问。而StringBuffer是线程安全的。

  • 然而,StringBuilder相较于StringBuffer执行速度更快,因此在多数情况下仍然可以使用StringBuilder。

  • 这是StringBuilder的部分源码

  • ![[博客/Java/Pasted image 20240626204134.png]]

  • 这是StringBuffer的部分源码

  • ![[博客/Java/Pasted image 20240626204245.png]]

  • 通过观察我们可以发现,StringBuilder的方法均没有添加synchronized,而StringBuffer的方法均添加了synchronized来保证线程安全。

来点小题

(以下均不考虑常量池的存在)

String str = new String(“ab”); 会创建多少个对象?

  • "ab"是一个字符串字面量,会在编译时生成一个字符串对象。
  • new String(“ab”) 会创建一个新的字符串对象,并且这个对象的内容是 “ab”。
  • 共创建两个对象。

String str = new String(“a”) + new String(“b”); 会创建多少个对象?

  • "a"和"b"是两个字符串字面量,会在编译时生成两个字符串对象。
  • new String(“a”) 会创建一个新的字符串对象,并且这个对象的内容是 “a”。
  • new String(“b”) 会创建一个新的字符串对象,并且这个对象的内容是 “b”。
  • new String(“a”) + new String(“b”) 会进行字符串拼接,字符串拼接会生成一个新的字符串对象,其内容是拼接后的结果 “ab”。这个新对象是通过 StringBuilder 或者 StringBuffer拼接后再通过 toString()方法生成的。
  • 共创建五个对象。
  • 33
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值