.net core将datatable转换成字符串拼接_Java面试整理-基础篇6.字符串(String)

本文详细介绍了Java中字符串的不可变性,包括substring在JDK6和JDK7的区别,replace与replaceAll的用法,以及多种字符串拼接方式的性能对比。同时,讨论了String.valueOf与Integer.toString的联系,以及JDK7开始对String支持switch的情况。
摘要由CSDN通过智能技术生成

1.什么是字符串的不可变性?

字符串的不可变性是指,一旦在内存(堆)中创建了一个字符串,它就不能被改变。所有字符串方法都没有改变字符串本身,而是返回了一个新对象。什么意思呢?

public class Example {public static void main(String args[]) {String name = "string1";System.out.println("string1");//输出为:string1name = "string2";System.out.println("string2");//输出为:string2}

我们看以上代码段,内存中的过程如下图所示

858406e1909350517d8708b652b00783.png


Java对不同的字符串值会在堆中分别为他们开辟一个空间。当我们将name从string1改变为string2时,实际上是将name在栈中对string1的引用覆盖为string2的引用。
字符串这种用新值的地址覆盖旧值的地址,但旧值的引用对象还存在堆中的现象,称为字符串的不可变性。


2.JDK6和JDK7中substring的原理和区别?

首先贴上JDK6和JDK7中的关键代码

//JDK 6String(int offset, int count, char value[]) {    this.value = value;    this.offset = offset;    this.count = count;}public String substring(int beginIndex, int endIndex) {    return  new String(offset + beginIndex, endIndex - beginIndex, value);}//JDK 7public String(char value[], int offset, int count) {    this.value = Arrays.copyOfRange(value, offset, offset + count);}public String substring(int beginIndex, int endIndex) {    int subLen = endIndex - beginIndex;    return new String(value, beginIndex, subLen);}

我们知道字符串有不可变性,所以在调用substring方法的时候,原字符串会指向一个新的字符串。JDK6中调用substring方法时,会创建一个新的string对象,但这个string的值仍然指向堆中的同一个字符数组。只是count和offset不同。这会有什么问题呢,如果你有一个很长的字符串,需要的只是一小段,可是却引用了整个字符串,那么这个很长的字符数组就会一直被引用,无法被回收。
JDK7针对JDK6存在的问题做了改进,substring方法会在堆内存中创建一个新的数组。

3.replace、replaceAll有什么区别?

String s = "string.test.txt";System.out.println(s.replace(".", "#"));//string#test#txtSystem.out.println(s.replaceAll(".", "#"));//###############

直接看代码,replace是针对字符的全替换,replaceAll是针对正则的全替换,"." 在正则中表示除了换行符之外的任意字符。


4.字符串的"+"是怎么实现的(String对"+"的重载)?

Java实际上没有运算符的重载,但对String对象而言,可以直接将两个String对象的字符串值相加即"+"。乍看是对"+"的重载,实际上这只是JVM的语法糖。String的"+"是由StringBuilder以及他的append、toString两个方法实现的。

5.字符串的拼接有几种方式,有什么什么区别?

1. "+"可以用字符串与任意类型"+"号拼接,编译器对其做了优化,使用StringBuilder的append方法进行追加,但是每执行一次都会创建一个StringBuilder对象,且会调用toString方法转换成字符串,所以开销很大。执行一次字符串"+",相当于 new StringBuilder(string).append("string").toString();
2. String的 contact() 方法
调用和传入都必须是字符串,且调用方不能为null,其实是一次数组的拷贝,虽然在内存中的处理都是原子性操作,速度很快,但最后的return语句会创建一个新String对象,限制了concat方法的速度。
3. StringUtils.join() 方法
适用于将ArrayList转换成字符串
4. StringBuffer的 append() 方法
5. StringBuilder的 append() 方法
StringBuffer 和 StringBuilder 的 append()都继承自AbstractStringBuilder,整个逻辑只做字符数组的加长,拷贝,到最后也不会创建新的String对象,所以速度很快,完成拼接处理后在程序中用strBuffer.toString()得到最终的字符串。
综上
1. "+" 和 contact() 适用于小数据量的操作,代码简洁,但时间和空间成本都很高,不能用来做大批量数据的处理。2. StringUtils.join() 适用于将ArrayList转换成字符串,适用于大批量,可以省掉循环读取ArrayList的代码。3. StringBuffer的 append() 和 StringBuilder的append() 本质是一样的,都继承自AbstractStringBuilder,效率最高,大批量的数据处理最好选择这两种方法。

6.String.valueOf和Integer.toString有什么区别?

int i = 4;String i1 = "" + i;String i2 = String.valueOf(i);

如上代码

1. 实际上String.valueOf(i)也是调用Integer.toString(i)来实现的。

2. String i1 = "" + i则是String i1 = (new StringBuilder()).append(i).toString();


7.switch支持String吗?

JDK7前不支持,JDK7及之后支持,实际上JDK7是通过调用switch中string.hashCode将string转换为int来支持switch的。

## 附言

* 转载请注明出处

* 更多文章,请关注公众号《百育科技》,公众号会定期按系列整理文章

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值