赞
踩
只要对String字符串进行了修改,都需要在字符串常量池中找到修改后对应的字符串,若没有则重新new一块地址给当前字符串变量,若有则将该字符串地址给到当前字符串变量。不能在原来的字符串地址上进行修改。
这里的s1,s2是变量而不是对象,对象是new来的。
比如String s=new String(“abc”);这里的“abc”就是对象
public class Demo { public static void main(String[] args) { /* String:字符串,声明为final,不可被继承 1.实现了Serializable接口:表示字符串是支持序列化的 2.实现了Comparable接口:表示String可以比较大小 3.内部定义了final cahr[] value用于存储字符串数据 4.代表不可变的字符序列。不可变性。 5.String比较特别,明明是个类,却不用new,直接字面量定义,但它不是基本数据类型 */ String s1="abc";//字面量的定义方式,只有String这个类可以 String s2="abc"; System.out.println(s1==s2);//比较s1和s2的地址值; } }
输出:true
通过字面量的定义方式给字符串赋值时
字符串“abc”将被存储到字符串常量池中,字符串常量池不会存储两个相同的字符串,所以s1中的“abc”与s2中的“abc”是同一个。
整体过程是:先给s1一个地址比如0x1212,s1=“abc”,则“abc”地址也为0x1212,s2出现时,先在字符串常量池中找有没有“abc”,有则将“abc”的地址给到s2,所以s1和s2的地址是相同的。
当改变字符串s1的值时:
当对字符串重新赋值时,需要重新指定一个内存区域赋值,不能使用原有的value进行赋值。
字符串常量池中新造一个“hello”,将新地址给到s1,所以s1与s2的地址不相同了。且s2的值不会随s1的改变而改变。
public class Demo {
public static void main(String[] args) {
String s1="abc";//字面量的定义方式
String s2="abc";
s1="hello";
System.out.println(s1==s2);//比较s1和s2的地址值;
}
}
当对现有字符串进行连接操作时,也需要重新指定内存区域赋值,不能使用原有的value进行赋值
public class Demo {
public static void main(String[] args) {
String s1="abc";//字面量的定义方式
String s2="abc";
s1+="def";
System.out.println(s1==s2);//false
}
}
当调用String的replace()方法修改字符串时,也必须重新指定内存区域赋值
public class Demo {
public static void main(String[] args) {
String s1="abc";//字面量的定义方式
String s2=s1.replace('a','m');
System.out.println(s1==s2);//false
}
}
String str1=“abc”;与String str2=new String (“abc”);的区别?
str1的地址是“abc”的,value是个引用类型,指向的是“abc”的地址值,value本身也有地址,str2的地址是value的地址。修改str2的值时并不会修改str1的值,因为字符串的不可变性。也就是说value会重新指向一个常量池中的新地址。
public class Demo { public static void main(String[] args) { /* String 实例化的方式: 方式一:通过字面量定义的方式 方式二:通过new+构造器的方式 */ //此时s1和s2的数据"javaEE"声明在方法区中的字符串常量池中。 String s1="javaEE"; String s2="javaEE"; //通过new+构造器的方式 //此时的s3和s4保存的地址值,是数据在堆空间开辟空间以后对应的地址 String s3=new String("javaEE"); String s4=new String("javaEE"); System.out.println(s1==s2);//true System.out.println(s3==s4);//false System.out.println(s1==s3);//false System.out.println(s1==s4);//false } }
相关解释说明
s1和s2因为字符串值相同,在字符串常量池中指向的是同一个字符串地址。
s3和s4虽然字符串相同,但在堆空间中new了两块地址value3和value4,value3和value4存储的都是字符串常量池中的同一个字符串地址“javaEE”,但value3和value4的地址不同,则s3和s4的地址也不同。
面试题:
String s=new String(“abc”);方式创建对象,在内存中创建了几个对象?
答:两个:一个是堆空间中new结构,另一个是char[ ]对应的常量池中的数据"abc";
public class Demo { public static void main(String[] args) { String s1="javaEE"; String s2="hadhoop"; String s3="javaEEhadhoop"; String s4="javaEE"+"hadhoop"; String s5=s1+"hadhoop"; String s6="javaEE"+s2; String s7=s1+s2; System.out.println(s3 == s4);//true System.out.println(s3 == s5);//false System.out.println(s3 == s6);//false System.out.println(s3 == s7);//false System.out.println(s5 == s6);//false System.out.println(s5 == s7);//false System.out.println(s6 == s7);//false String s8=s5.intern(); //返回值得到的s是使用的常量池中已经存在的"javaEEhadoop" System.out.println(s3 == s8);//true String s9=s7.intern(); System.out.println(s9 == s3);//true } }
只有s3和s4初始化时右边都是字符串常量,其在字符串常量池中完成字符串拼接。其余的s5,s6,s7具有变量参与,相当于在堆空间中new了一块新地址,所以都不相等。如果将右边的变量改为常量,则是在字符串常量池中操作。
例:
String str1="java";
String str2="EE";
String str="javaEE";
String str3=str1+"EE";
System.out.println(str==str3);//false
final String str4="java";
String str5=str4+"EE";
System.out.println(str==str5);//true
面试题
public class Demo {
public static void main(String[] args) {
String str=new String("good");
char[] ch={'t','e','s','t'};
change(str,ch);
System.out.println(str);
System.out.println(ch);
}
public static void change(String str,char ch[]){
str="test ok";
ch[0]='b';
}
}
因为String的不可变性,所以change方法内的str只能重新在堆内存中重新new一块地址,而main方法中的str仍在原来的地址,所以值不改变。
String s1="helloworld";
System.out.println(s1.length());//10
System.out.println(s1.charAt(0));//h 获取第n个字符 字符串没有数组下标形式
System.out.println(s1.isEmpty());//false
s1="";
System.out.println(s1.isEmpty());//true
public class Demo { public static void main(String[] args) { String s1="helloworld"; //将字符串全部小写 System.out.println(s1.toLowerCase());//helloworld //将字符串全部大写 System.out.println(s1.toUpperCase());//HELLOWORLD System.out.println(s1);//helloworld s1的内容仍不变 String s2="hello world "; //trim()去除字符串首尾空格,中间的不去除 String s3=s2.trim(); System.out.println(s2+"-----");//hello world ----- System.out.println(s3+"-----");//hello world----- String s4="hello"; String s5="world"; String s6=s4+s5; System.out.println(s1.equals(s6));//true 比较字符串内容是否相同 String s7=s6.toUpperCase();//HELLOWORLD //忽略字符串的大小写比较内容是否相同 System.out.println(s7.equalsIgnoreCase(s1));//true //拼接字符串 等价于用“+” String s8=s4.concat("abc"); System.out.println(s8);//helloabc //compareTo()比较字符串大小:按顺序挨个比较 //因为w-a=-22,所以输出-22 System.out.println(s8.compareTo(s1));//-22 s8="北京我爱你"; System.out.println(s8.substring(2));//我爱你 //注意第2个数是最后一个字符对应下标+1 System.out.println(s8.substring(2, 5));//我爱你 } }
public class Demo1 { public static void main(String[] args) { String str1="helloworld"; //检测是否以指定后缀结尾 boolean b=str1.endsWith("rld"); System.out.println(b);//true //检测是否以指定前缀开头 System.out.println(str1.startsWith("He"));//false //检测是否从指定索引开始的子字符以指定内容开头 System.out.println(str1.startsWith("ll",2));//true //判断字符串是否包含子字符串 System.out.println(str1.contains("hell"));//true //返回指定子字符串在此字符串中第一次出现处的索引 System.out.println(str1.indexOf("lo"));//3 System.out.println(str1.indexOf("ww"));//没有则返回-1 //从指定索引处开始找子串是否存在于字符串中 System.out.println(str1.indexOf("lo",5));//-1 String str2="hellorporpp"; //从后面开始找子串,返回第一个出现的子串索引 System.out.println(str2.lastIndexOf("or"));//7 //从指定索引处开始往左找第一个匹配的子串 System.out.println(str2.lastIndexOf("or",6));//4 } }
什么情况下str.lastIndexOf(“str1”);和str.IndexOf(“str1”);返回值相同?
情况一:字符串中只有一组与子串相匹配
情况二:一个都没有(返回-1)
public class Demo1 { public static void main(String[] args) { String str1="北京尚硅谷教育北京"; String str2=str1.replace('北','东'); System.out.println(str1);//北京尚硅谷教育北京 System.out.println(str2);//东京尚硅谷教育东京 String str3=str1.replace("北京","上海"); System.out.println(str3);//上海尚硅谷教育上海 String str4="464dsvf8svd646fbdfba4a6va"; //d表示数字(正则表达式),+表示可能有多个数字 //将字符串中的数组替换为指定字符串 String str5=str4.replaceAll("\\d+",","); System.out.println(str4);//464dsvf8svd646fbdfba4a6va System.out.println(str5);//,dsvf,svd,fbdfba,a,va //若字符串开头(^)或结尾($)有","则用“”代替,也就是去除“,” String str6=str4.replaceAll("\\d+",",").replaceAll("^,|,$",""); System.out.println(str6);//dsvf,svd,fbdfba,a,va String str7="12345"; //判断str是否全部由数字组成 boolean matches=str7.matches("\\d+"); System.out.println(matches);//true //判断是否是一个杭州的固定电话 String tel="0571-453428999"; matches=tel.matches("0571-\\d{7,8}");//表示后面还有7~8位数字 System.out.println(matches);//false 有9位数字 //切片 用“|”将字符串切割开,并用字符串数组接收 str7="hello|world|java"; String[] strs=str7.split("\\|"); for(int i=0;i<strs.length;i++){ System.out.print(strs[i]+" ");//hello world java } } }
public class Demo1 {
public static void main(String[] args) {
//String--->基本数据类型、包装类
// 调用包装类的静态方法:parseXxx(str)
String str="123";
int num=Integer.parseInt(str);
//基本数据类型、包装类--->String
//调用String重载的valueOf(xxx)
String s=String.valueOf(num);//"123"
//或者直接连接“”
String s1=num+"";//"123"
}
}
String与char[ ]
/*
String 与char[]之间的转换
*/
//String--->char[] 调用String的toCharArray
String str="abc123";
char[] chars=str.toCharArray();
for(int i=0;i<chars.length;i++){
System.out.print(chars[i]+" ");
}
System.out.println();
//char[]--->String 调用String的构造器
char[] arr=new char[]{'h','l','o'};
String str1=new String(arr);
System.out.println(str1);
String与byte[ ]
说明:解码是,要求解码使用的字符集必须与编码时使用的字符集一致,否则出现乱码。
import java.io.UnsupportedEncodingException; import java.util.Arrays; public class Demo { public static void main(String[] args) throws UnsupportedEncodingException { /* String 与byte[](字节数组)之间的转换 */ //编码:String--->byte[] 调用String的getBytes() String str1="abc123"; byte[] bytes=str1.getBytes();//使用默认的字符集进行转换 System.out.println(Arrays.toString(bytes));//[97, 98, 99, 49, 50, 51] String str2="你好中a"; byte[] gbks=str2.getBytes("gbk");//使用gbk字符集进行编码 System.out.println(Arrays.toString(gbks));//[-60, -29, -70, -61, -42, -48, 97] //解码:byte[]--->String 调用 String str3=new String(bytes);//使用默认的字符集进行解码 System.out.println(str3);//abc123 //String str4=new String(gbks);乱码 原因:编码集和解码即不一致 String str4=new String(gbks,"gbk"); System.out.println(str4);//你好中a } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。