一、字符串基础
1、如何创建一个字符串?
(1)直接用双引号来表示字符串(存储在字符串常量池中:池中没有就建立,池中有就直接使用)-- 最常用
(2)用new的形式实现对象的创建
2、String类的特点:String类是不可变类(public final class String),字符串对象一旦被初始化就不会被改变 -- 常量
注:String对象不可变,所以可以共享,即直接使用。字符串缓冲区支持可变的字符串
3、"abc" == new String("abc"); //false
(1)String s = "abc":在字符串常量池中创建了一个字符串对象abc,并把地址值赋给了引用类型变量s(在编译时期确定下来,字符串直接量由JVM使用常量池来管理 -- JVM常量池保证相同的字符串直接量只有一个)
(2)String s = new String("abc"):一共产生了两个对象,一个new,一个字符串对象(被new的对象在堆内存中维护)。在运行时创建出来,JVM会先使用常量池来管理"abc"直接量,再调用String类的构造器来创建一个新的String对象,新创建的String对象被保存在堆内存中
即 在堆内存中用new创建了一个String对象,这个对象在构造的时候,接收了一个字符串对象 -- 参数传递
说明:
(1)常量池中的字符串对象由String类来维护。其实它本身也会在堆中产生一个池子,专门用来存储这些字符串对象
(2)常量池:专门用于管理在编译期被确定并被保存在已编译的.class文件中的一些数据。它包括了关于类、方法、接口中的常量,还包括字符串常量。常量池中的对象本身是可以被共享的 -- 减少内存的占用,提高效率
4、String类覆盖了Object中的equals()方法,比较的是内容而不是地址值(String类覆盖了Object中除了getClass()外的所有方法,包括:equals()、hashCode()、toString())
5、String s = new String():构造一个空字符串,已经有引用指向了,与 String s = "" 等效(地址值不同,内容相同)
注:与 String s = null 不等效,null不是对象,是个常量值空,此时还没有引用指向
6、使用API,先明确功能有无参数、参数类型、结果类型,即参数列表和返回值类型,再到API中查找
二、String类的构造函数
参数可为:空、String、byte[]、char[]、int[]、StringBuffer、StringBuilder
1、将字节数组变成字符串:
public String(byte[] bytes, int offset, int length):数字到字符串中会变成字符,会自动将其中的数字进行ASCII码表查表转换(offset:从哪里开始,length:取几个)
注:字节是计算机存储信息的基本单位(最小单位),一个字节等于8位。gbk编码中,一个汉字字符存储需要2个字节,一个英文字符存储需要1个字节。汉字对应的字节值为负数,原因在于每个字节是8位,最大值不能超过127,而汉字转换为字节后超过127,超过就会溢出,以负数的形式显示。
应用:要把很多最小单位组合成一个字符串展示出来,或者把字符串变成最小单位存储起来
byte[] bytes = {3, 65, 36, 78, 41};
String str = new String(bytes, 1, 3); // A$N
2、将字符数组变成字符串:
public String(char[] value, int offset, int length):字符本身就是字符串中的单元(字符串是由字符组成的)
char[] value = {'a','e','D','M','q','W'};
str = new String(value); //aeDMqW
3、将int型数组变成字符串:
public String(int[] codePoints, int offset, int count)
4、将字符串缓冲区中的内容变成字符串:
public String(StringBuffer buffer)
5、将字符串生成器中的内容变成字符串:
public String(StringBuilder builder)
三、String类的常见功能
1、获取:
(1)获取字符串的长度:public int length()
String str1 = "";
//空格是个字符,有自己定义的ASCII码值
String str2 = " ";
System.out.println(str1.length()); //0
System.out.println(str2.length()); //1
(2)返回指定索引处的char值:public char charAt(int index)
注:index > length,抛出StringIndexOutOfBoundsException,字符串角标越界异常
(3)返回指定索引处的char字符对应的数字值:public int codePointAt(int index)
(4)返回指定索引之前的char字符对应的数字值:public int codePointBefore(int index)
String str = "12s9 ahd+sdky";
System.out.println(str.charAt(5)); //a
System.out.println(str.codePointAt(5)); //97
System.out.println(str.codePointBefore(6)); //97
(5)返回指定字符在字符串中第一次出现的索引:public int indexOf(int ch, int fromIndex)
注:参数fromIndex可以省略。fromIndex > 0,从0开始查找;fromIndex > length,返回-1。若参数是char类型会自动转换成int类型(自动类型提升)
(6)返回指定子字符串在字符串中第一次出现的索引:public int indexOf(String str, int fromIndex):较常用
(7)返回指定字符在字符串中最后一次出现的索引:public int lastIndexOf(int ch, int fromIndex)
(8)返回指定子字符串在字符串中最后一次出现的索引:public int lastIndexOf(String str, int fromIndex)
注:indexOf()有两个功能:一是索引位置,二是判断存在,不存在时返回-1(判断存在还有一个方法是contains(str),不存在时返回false)
(9)获取字符串的子串:public String substring(int beginIndex, int endIndex):包含头不包含尾
2、转换
(1)将字符串变成字符串数组 / 根据指定正则表达式的匹配拆分字符串(切割):public String[] split(String regex, int limit)
注:limit影响所得数组的长度,可不要该参数,不写默认为0。若正常切割所得数组长度为n,如果 limit < 0 或 limit > n ,和正常情况一致;如果 limit = 0 ,会把分割后所得数组结尾的空字符串丢弃;如果 0 < limit <n ,限制最后分割得到数组的长度为limit
String str = "boo:and:foo";
System.out.println(Arrays.deepToString(str.split(":", 2))); //[boo, and:foo]
System.out.println(Arrays.deepToString(str.split(":", 5))); //[boo, and, foo]
System.out.println(Arrays.deepToString(str.split(":", -2)));//[boo, and, foo]
System.out.println(Arrays.deepToString(str.split("o", 2))); //[b, o:and:foo]
System.out.println(Arrays.deepToString(str.split("o", 5))); //[b, , :and:f, , ]
System.out.println(Arrays.deepToString(str.split("o", -2)));//[b, , :and:f, , ]
System.out.println(Arrays.deepToString(str.split("o", 0))); //[b, , :and:f]
System.out.println(Arrays.deepToString(str.split("o"))); //[b, , :and:f]
(2)将字符串变成字符数组:public char[] toCharArray()
注:可用于计算字符串中的字数(中文、英文、符号长度都为1)
String str = "boo.and.foo,张三,李四";
System.out.println(str.toCharArray().length); //17
(3)将字符串变成字节数组:public byte[] getBytes()
注:一个中文两个字节
(4)将字符串中的所有字母都转成小写:public String toLowerCase()
(5)将字符串中的所有字母都转成大写:public String toUpperCase()
注:会在字符串常量池中生成新的字符串,所以方法的返回值类型是String。只对字母有效,中文等不会被转换
Character类中有几个静态方法将指定字符变成大写或小写:
public static char toUpperCase(char ch)
public static int toUpperCase(int codePoint)
public static char toLowerCase(char ch)
public static int toLowerCase(int codePoint)
(6)用指定字符串替换第一个匹配正则表达式的子字符串:public String replaceFirst(String regex, String replacement)
(7)用指定字符串替换所有匹配正则表达式的子字符串:public String replaceAll(String regex, String replacement)
(8)将字符串中的内容进行替换,用newChar替换oldChar:public String replace(char oldChar, char newChar)
注:replace()中传入什么就匹配什么,不含正则表达式的转义。替换成功,在常量池中创建新的字符串;替换失败,返回原串
String str = "a.b.你";
System.out.println(str.replace(".", "-")); //a-b-你
System.out.println(str.replace("\\.", "-")); //a.b.你
System.out.println(str.replaceAll(".", "-")); //-----
System.out.println(str.replaceAll("\\.", "-")); //a-b-你
System.out.println(str.replaceFirst("\\.", "-")); //a-b.你
System.out.println(str.replace("你", "wo")); //a.b.wo
System.out.println(str.replaceAll("你", "wo")); //a.b.wo
System.out.println(str.replaceFirst("你", "wo")); //a.b.wo
(9)去除字符串两端(头尾)的空格,否则返回原串:public String trim()
注:凡是获取用户输入信息时,都要做trim()操作,方便存储和校验
(10)将指定字符串连接到该字符串尾部(功能同"+"连接):public String concat(String str)
(11)返回xxx类型参数的字符串表示形式,即将基本数据类型变成字符串:public static String valueOf(xxx value)
注:参数类型xxx可以是char、char[]、int、long、float、double、boolean、Object(如果参数为null,则字符串等于"null",否则返回obj.toString()的值)
eg:返回指定子数组的字符串表示形式:public static String valueOf(char[] data, int offset, int count)
3、判断
(1)比较两个字符串的内容是否相同,区分大小写:public boolean equals(Object anObject):覆盖Object中的方法
(2)忽略大小写比较两个字符串的内容是否相同:public boolean equalsIgnoreCase(String anotherString)
具体实现:先全部转为大写或小写,再进行equals()比较
(3)判断字符串是否包含指定字符串。当且仅当字符串包含指定的char值序列时,返回true:public boolean contains(CharSequence s)
(4)将字符串与指定的StringBuffer比较,当且仅当String与指定StringBuffer表示相同的字符序列时,结果才为true:public boolean contentEquals(StringBuffer sb)
(5)将字符串与指定的CharSequence比较,当且仅当String与指定序列表示相同的char值序列时,结果才为true:public boolean contentEquals(CharSequence cs)
(6)判断从指定索引开始的子字符串是否以指定的前缀开始:public boolean startsWith(String prefix, int toffset)
注:如果prefix为空,则返回true;如果 toffset <0 或 toffset > length,返回false
(7)判断字符串是否以指定的后缀结束:public boolean endsWith(String suffix)
(8)判断字符串是否为空,当且仅当length()为0时返回true:public boolean isEmpty()
(9)测试两个字符串区域是否相等:public boolean regionMatches(boolean ignoreCase, int toffset, String other, int ooffset, int len)
注:要比较的String的子串从toffset开始,长度为len,参与比较的other的子串从ooffset开始,长度为len。ignoreCase参数可省略
4、比较
(1)比较有三种结果:大、小、一样,而boolean只有两种结果:true、false
(2)按字典顺序比较两个字符串(基于字符的Unicode值 或 ASCII码表顺序):public int compareTo(String anotherString)
注:str和参数比较,如果相同位置上char值不同,则返回Unicode值的差;如果相同位置上char值都相同,则返回length差;如果返回0,则表示两个字符串的equals()结果为true
(3)按字典顺序比较两个字符串,不考虑大小写:public int compareToIgnoreCase(String str)
(4)基本类型的数据比较大小,用操作运算符(<、=、>)。对象的比较,调用方法完成
5、intern()方法
(1)返回字符串对象的规范化表示形式:public String intern()
(2)调用intern()方法时,如果该字符串在字符串缓冲池中已经存在(用equals()确定),则返回该字符串的引用。否则,将字符串添加到字符串缓冲池中,并返回引用 -- 操作的是字符串缓冲池中的内容
(3)new String("abc").intern() == "abc" //true
String s1 = new String("abc");
String s2 = s1.intern(); //返回字符串缓冲池中对象。有就直接用,没有就先添加再用
String s3 = "abc";
System.out.println(s1 == s2); //false
System.out.println(s1 == s3); //false
System.out.println(s2 == s3); //true
四、CharSequence
1、接口CharSequence字符序列(按照一定顺序排列),所有已知实现类:CharBuffer、Segment、String、StringBuffer、StringBuilder
2、CharSequence和String都能用于定义字符串,但CharSequence的值是可读可写序列,而String的值是只读序列
五、关于String的编程题目+代码
https://pan.baidu.com/s/1kXExaAOmJ2TruWz-R_R3hA 密码:1dh8