String实现了Serializable接口(表示字符串是支持序列化的)、实现了Comparable接口(表示String可以比较大小)。/**
* 注意:
* 1.通过字面量的方式(区别于new)给一个字符串赋值,此时的字符串值声明在字符串常量池中。
* 2.字符串常量池中是不会存储相同内容的字符串的。
* 3.当对字符串重新赋值时,需要重写指定内存区域赋值,不能使用原有的value进行赋值。
* 4.当对现有的字符串进行连接操作时,也需要重新指定内存区域赋值,不能使用原有的value进行赋值。
*/
public class StringTest1 {
public static void main(String[] args) {
String s1 = "aaa";//字面量的定义方式
String s2 = "aaa";
System.out.println(s1==s2);//返回结果:true,二者指向相同的地址
String s3 = new String("bbb");
String s4 = new String("bbb");
System.out.println(s3==s4);//返回结果:false
}
}
String str="abc";与String str2=new String ("abc")的区别?
字符串常量存储在方法区中的字符串常量池,目的是共享。
字符串非常量对象存储在堆中。
面试题:String s=new String("abc");方式创建对象,在内存中创建了几个对象?
两个,一个是堆空间的new结构,另一个是char[]对应的常量池中的数据:“abc”
/**
* 案例:String不同拼接操作的对比。
* 结论:
* 1.常量与常量的拼接结果在常量池,且常量池中不会存在相同内容的常量。
* 2.只要其中有一个变量(变量名)参与,结果就在堆中。
* 3.如果拼接的结果调用intern()方法,返回值就在常量池中
*/
public class StringTest1 {
public static void main(String[] args) {
String s1 = "aaa";//字面量的定义方式
String s2 = "bbb";
String s3 = "aaabbb";
String s4 = "aaa"+"bbb";
String s5 = s1+"bbb";
String s6 = "aaa"+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
String s8 = s5.intern();//返回值得到的s8使用的是常量池中已经存在的
System.out.println(s3 == s8);//true
}
}
常用方法1:int length():返回字符串的长度: return value.length.
char charAt(int index):返回某索引处的字符:return value[index].
boolean isEmpty():判断是否是空字符串: return value.length=0.
String toLowerCase():使用默认语言环境,将String中的所有字符转换为小写.
String toUpperCase():使用默认语言环境,将String中的所有字符转换为大写.
String trim():返回字符串的副本,忽略前导空自和尾部空白.
boolean equals(Object obj):比较字符串的内容是否相同.
boolean equalsIgnoreCase(String anotherString):与equals方法类似,忽略大小写.
String concat(String str):将指定字符串连接到此字符串的结尾。等价于用“+” .
int compareTo(String anotherString):比较两个字符串的大小
String substring(int beginlndex):返回一个新的字符串,它是此字符串的从beginindex开始截取到最后的一个子字符串。
String substring(int beginlndex,int endlndex):返回一个新字符串,它是此字符串从beginlndex开始截取到endlndex(不包含)的一个子字符串。
//案例一:
public static void test1(){
String s1 = "HelloWord";
System.out.println(s1.length());//9
System.out.println(s1.charAt(0));//H
System.out.println(s1.isEmpty());//false
System.out.println(s1.toLowerCase());//helloword
System.out.println(s1.toUpperCase());//HELLOWORD
String s2 = " Hello World ";
System.out.println("---"+s2.trim()+"---");//---Hello World---
}
public static void test2(){
String s1 = "Hello World";
String s2 = "hello world";
String s3 = new String("Hello World");
String s4 = new String("hello world");
System.out.println(s1.equals(s2));//false
System.out.println(s1.equalsIgnoreCase(s2));//true
System.out.println(s3.equals(s4));//flase
System.out.println(s3.equalsIgnoreCase(s4));//true
System.out.println(s1.compareTo(s2));//-32
System.out.println(s1.substring(1));//ello World
System.out.println(s1.substring(1,8));//ello Wo
}
常用方法2:boolean endsWith(String suffix):测试此字符串是否以指定的后缀结束。
boolean startsWith(String prefix):测试此字符串是否以指定的前缀开始。
boolean startsWith(String prefix,int toffset):测试此字符串从指定索引开始的子字符串是否以指定前缀开始.
boolean contains(CharSequence s):当且仅当此字符串包含指定的char值序列时,返回true。
int indexOf(String str):返回指定子字符串在此字符串中第一次出现处的索引.
int indexOf(String str,int fromIndex):返回指定子字符串在此字符串中第一次出现处的索引,从指定的索引开始.
int lastIndexOf(String str):返回指定子字符串在此字符串中最右边出现处的索引.
int lastIndexOf(String str,int fromIndex):返回指定子字符串在此字符串中最后一次出现处的索引,从指定的索引开始反向搜索。
注: indexOf()和lastIndexOf()方法如果未找到都是返回-1.
//案例二:
public static void test3(){
String s1 = "hgkwylb";
System.out.println(s1.endsWith("wylb"));//true
System.out.println(s1.endsWith("gstx"));//false
System.out.println(s1.startsWith("hgk"));//true
System.out.println(s1.startsWith("kw",2));//true
String s2 = "wy";
System.out.println(s1.contains(s2));//true
String s3 = "hellorworld";
System.out.println(s3.indexOf("or"));//4
System.out.println(s3.indexOf("or",5));//7
System.out.println(s3.lastIndexOf("or"));//7
System.out.println(s3.lastIndexOf("or",4));//4
/**
* 什么情况下,indexOf(str)和lastIndexOf(str)返回值相同。
* 情况一:存在唯一的一个str.
* 情况二:不存在str.
*/
}
常用方法3:替换:
String replace(char oldChar,char newChar):返回一个新的字符串,它是通过用newChar替换此字符串中出现的所有oldChar得到的(替换char).
String replace(CharSequence target,CharSequence replacement):使用指定的字面值替换序列替换此字符串所有匹配字面值目标序列的子字符串(替换字符串)。
String replaceAll(String regex,String replacement):使用给定的replacement替换此字符串所有匹配给定的正则表达式的子字符串。
String replaceFirst(String regex,String replacement):使用给定的replacement替换此字符串匹配给定的正则表达式的第一个子字符串。
匹配:
boolean matches(String regex):告知此字符串是否匹配给定的正则表达式.
切片:
String[] split(String regex):根据给定正则表达式的匹配拆分此字符串。
String[] split(String regex,int limit):根据匹配给定的正则表达式来拆分此字符串,最多不超过limit个,如果超过了,剩下的全部都放到最后一个元素中。
//案例三:
public static void test4(){
String s1 = "不能说的秘密,不能说的秘密";
System.out.println(s1.replace("的","de"));//不能说de秘密,不能说de秘密
System.out.println(s1.replace("秘密","mimi"));//不能说的mimi,不能说的mimi
}
String与基本数据类型转换:public class StringTest1 {
public static void main(String[] args) {
/**
* 1.字符串--->基本数据类型、包装类
* Integer包装类的public static int parseInt(String s);
* 可以将由"数字"组成的字符串转换为整型。
* 类似的,使用java.lang包中的Byte,Short,Long,Float,Double类调相应的类方法可以将由"数字"字符组成的字符串,转化为相应的基本类型。
*/
String s1 = "123";
int i = Integer.parseInt(s1);
System.out.println(i);
String s2 = "false";
boolean b = Boolean.parseBoolean(s2);
System.out.println(b);
/**
* 2.基本数据类型、包装类--->字符串
* 调用String类的public String valueOf(int t)可将int型转换成字符串。
* 相应的valueOf(byte b),valueOf(long l),valueOf(float f),valueOf(double d),valueOf(boolean b)可由参数的相应类型到字符串的转换。
*/
int a = 123;
String s = String.valueOf(a);
System.out.println(s);
Integer integer = new Integer(123);
String s3 = String.valueOf(integer);
System.out.println(s3);
}
}
String与char[]之间的转换: public static void test2(){
/**
* 1.字符数组--->字符串
* String类的构造器:String(char[])和String(char[],int offset,int length)分别用字符串组中的全部字符和部分字符创建字符串对象。
* 2.字符串--->字符数组
* public char[] toCharArray():将字符串中的全部字符存放在一个字符数组中的方法。
* public void getChars(int srcBegin,int srcEnd,char[] dst,int dstBegin):提供了将指定索引范围内的字符串放到数组中的方法。
*/
//1.字符串--->字符数组
String s1 = "abc123";
char[] chars = s1.toCharArray();
System.out.println(chars[3]);//1
//2.字符数组--->字符串
char[] chars1 = {'h', 'g', 'k', 'h', 's'};
String s = new String(chars1);
System.out.println(s);//hgkhs
}
String与byte[]之间的转换:public static void test3() throws UnsupportedEncodingException {
/**
* 1.字符串--->字节数组
* public byte[] getBytes():使用平台的默认字符集将次String编码为byte序列,并将结果存储到一个新的byte数组中。
* public byte[] getBytes(String charsetName):使用指定的字符集将此String编码到byte序列,并将结果存储到新的byte数组。
* 2.字节数组--->字符串
* String(byte[]):通过使用平台的默认字符集解码指定的byte数组,构造一个新的String。
* String(byte[],int offset,int length):用指定的字节数组的一部分,即从数组起始位置offest开始取length个字节构造一个字符串对象。
*/
//1.字符串--->字节数组(编码)
String s1 = "abc中国";
byte[] bytes = s1.getBytes();//使用默认的字符集,进行转换
System.out.println(Arrays.toString(bytes));//[97, 98, 99, -28, -72, -83, -27, -101, -67]
byte[] gbks = s1.getBytes("gbk");//使用gbk字符集进行编码
System.out.println(Arrays.toString(gbks));//[97, 98, 99, -42, -48, -71, -6]
//2.字节数组--->字符串(解码)
String s = new String(bytes);
System.out.println(s);//abc中国
String gbk = new String(bytes, "gbk");
System.out.println(gbk);//abc涓浗
}
(2)StringBuffer、StringBuilder
/**
* String、StringBuffer、StringBuilder的异同
* String:不可变的字符序列;底层使用char[]存储。效率最差。
* StringBuffer:可变的字符序列;线程安全的、效率低;底层使用char[]存储。
* StringBuilder:可变的字符序列;JDK 5.0新增,线程不安全的、效率高;底层使用char[]存储。
*/
/**
* StringBuffer、StringBuilder的使用
* 1.源码分析:
* String str=new String();//char[] value=new char[0];
* String str1=new String("abc");//char[] value=new char['a','b','c'];
*
* StringBuffer sb1=new StringBuffer();//char[] value=new char[16];底层创建了一个长度是16的char[]数组
* sb1.append('a');//value[0]='a';
*
* StringBuffer sb2=new StringBuffer("abc");//char[] value=new char["abc".length+16];
* 问题1:System.out.println(sb2.length());//3
* 问题2:扩容问题:如果要添加的数据底层数组盛不下了,那么就扩容底层数组。
* 默认情况下,扩容为原来容量的2倍+2,同时将原有数组中的元素复制到新的数组中。
* 指定意义:开发当中,建议大家使用:StringBuffer(int capacity)或StringBuilder(int capacity);//创建一个指定长度的StringBuffer,避免频繁的扩容问题,提高效率。
*/
public static void test1(){
StringBuffer sb1 = new StringBuffer("abc");
sb1.setCharAt(0,'m');
System.out.println(sb1);//mbc
sb1.append("abc");
System.out.println(sb1);//mbcabc
}
StringBuffer常用方法:(StringBuilder方法改一下返回值即可) /*
StringBuffer append(***):提供了很多append()方法,用于进行字符串拼接。
StringBuffer delete(int start,int end):删除指定位置的内容。
StringBuffer replace(int start,int end,String str):把[start,end]位置替换为str.
StringBuffer insert(int offset,***):在指定位置插入***。
StringBuffer reverse():把当前字符序列逆转。
当append和insert时,如果原来value数组长度不够,可扩容。
public int indexOf(String str);
public String substring(int start,int end);
public int length();
public char charAt(int n);
public void setCharAt(int n,char ch);
*/
public static void test2(){
//重点:增、删、改、查、插、长度、遍历
StringBuffer sb1 = new StringBuffer();
System.out.println(sb1.append("abcdef"));//abcdef
System.out.println(sb1.deleteCharAt(1));//acdef
System.out.println(sb1.replace(2, 4, "周杰伦"));//ac周杰伦f
System.out.println(sb1.insert(2,"明明就"));//ac明明就周杰伦f
System.out.println(sb1.reverse());//f伦杰周就明明ca
}