String类是最终类,没有子类
java中所有的字符串直接量都是String类的对象
String类底层是由一个无法改变的字符数组(在jdk11中,换成了byte[]
)来实现数据存储
如果常量池中已经存在引用,后面的对象和前面的对象内容一致,前后共用一个常量池的引用—共享
public class StringDemo1 { public static void main(String[] args) { // str1指向方法区的常量池 String str1 = "ab"; // str2指向堆内存 String str2 = new String("ab"); // 如果常量池中已经存在引用,当后面的字符串对象和前面的相同,共享一个常量池的引用 String str3 = "ab"; // 如果 = 右边参与运算的都是直接量java会在编译时期进行优化直接计算结果再进行赋值 String str4 = "a" + "b"; String str5 = "a"; str5 += "b"; // str5 += "b";底层依赖于StringBuilder来完成拼接 // str5 = new StringBuilder("a").append("b").toString(); // 4个对象 // str5指向堆内存,但是和str2指向堆内存中不同的区域 System.out.println(str1 == str2); // false System.out.println(str1 == str3); // true System.out.println(str1 == str4); // true System.out.println(str1 == str5); // false System.out.println(str2 == str5); // false } }
+和StringBuilder(jdk1.5出现)拼接效率
String str="a"; //1 str+="b"; //4 //new StringBuilder("a").append("b").toString(); // "a":1 "b":2 "ab:"3 4 // new StringBuilder("a") 1 // new StringBuilder("ab") 2 // new String("ab") 3 // byte[]{b} 4
String[] ss = {...}; // String类数组,100个元素 // + 拼接 String str = ""; // 1 for (int eachItem: ss){ str += eachItem; // 每次创建3个对象 } // 一共创建301个对象 // StringBuilder拼接 StringBuilder sb =new String Builder(""); //1 for(String item:ss){ sb.append(item); // 1 } String s = sb.toString(); // 1 // 一共创建102个对象
public class StringDemo1 { public static void main(String[] args) { // 返回从1970年1月1日0时0分0秒到此刻的毫秒值 long start = System.currentTimeMillis(); // 用 + 拼接 // String str = ""; // for (int i = 0; i < 100000; i++){ // str += "a"; // } // 用StringBuilder拼接 StringBuilder sb = new StringBuilder(""); for (int i = 0; i < 100000; i++){ sb.append("a"); } String str = sb.toString(); long end = System.currentTimeMillis(); System.out.println(end - start); } }
在拼接大量数据时采用StringBuilder来拼接效率更高
StringBuffer和StringBuilder
StringBuilder—拼接效率较高、不安全(jdk1.5)
StringBuffer—拼接效率较低、安全(jdk1.0)
常用方法
charAt()
:返回指定索引的 char
值。
length()
:返回字符串的长度
toCharArray()
:把字符串转成字符数组
new String(char[] cs, int offset, int count)
:可以把字符数组的部分内容转成新的String类对象
public class StringDemo2 { public static void main(String[] args) { String str = "abdshf"; // 给定字符串的下标值返回对应的字符 System.out.println(str.charAt(2)); // 遍历字符串 // length() --- 表示字符串的长度 for(int i = 0; i < str.length(); i++){ System.out.println(str.charAt(i)); } // 把字符串转换成一个字符数组 char[] cs = str.toCharArray(); // 通过字符数组创建新的String类对象,有参构造 String s = new String(cs); String s1 = new String(cs,0,4); System.out.println(Arrays.toString(cs)); } }
compareTo(String anotherString)
:针对两个对象进行字典比较
compareToIgnoreCase(String str)
:忽略大小写差异
public class StringDemo3 { public static void main(String[] args) { String str1 = "sfdd"; String str2 = "sfddcsda"; // 字典比较 // 把两个字符串内容放到两个字符数组中 // 拿两个字符数组对应位置的字符做差值 // 如果差值不为0就当做方法返回值进行返回 // 如果差值为0就下标挪动到下一位,拿着两个字符数组对应位置元素做差值 // 如果所有差值都为0,最终以两个字符数组的长度之差作为方法的返回值进行返回 // 如果方法的返回值大于0表明前面的对象大于后面的对象 // 如果方法的返回值等于0表明前面的对象等于后面的对象 // 如果方法的返回值小于0表明前面的对象小于后面的对象 System.out.println(str1.compareTo(str2)); } }
concat(String str)
:把新字符串拼接到原字符串末尾,返回一个新的字符串
public class StringDemo4 { public static void main(String[] args) { String str = "asjfkla"; // 把新字符串拼接在原字符串末尾 // + 和 concat的区别 // 1. + 根据StringBuilder来拼接,concat基于数组扩容来拼接 // 2. concat只能和字符串进行拼接,+可以和任意数据做拼接 System.out.println(str.concat("123")); System.out.println(str); // 原字符串没有改变 } }
contains(CharSequence s)
:判断新串是否是原串的子串
public class StringDemo4 { public static void main(String[] args) { String str = "aslgjdflk"; // 判断是否为子串 System.out.println(str.contains("gjd")); } }
endsWith(String suffix)
:判断原串是否以新串结尾
startsWith(String prefix)
:判断原串是否以新串开头
public class StringDemo4 { public static void main(String[] args) { String str = "abc.txt"; System.out.println(str.endsWith(".txt")); System.out.println(str.startsWith("abc")); } }
equals(Object anObject)
: 先比较两个对象的地址值,如果不相等再依次比较两个对象的内容是否完全相等
equalsIgnoreCase(String anotherString)
:忽略大小写
public class StringDemo5 { public static void main(String[] args) { String str1 = "abc"; String str2 = "abc"; String str3 = new String("abc"); String str4 = "ABC"; // 对象 instanceof 父类/子类/本类 --- 判断对象与类的关系 // 测试它左边的对象是否是它右边的类的实例 // String ss = new String(); // System.out.println(ss instanceof Object); // 先比较两个对象的地址值,如果不相等再依次比较两个对象的内容是否完全相等 System.out.println(str1.equals(str2)); // true System.out.println(str1.equals(str3)); // true // 忽略大小写 System.out.println(str1.equalsIgnoreCase(str4)); // true } }
getBytes()
:按照指定的编码把字符串转成字节数组
String(byte[] bytes, int offset, int length, String charsetName)
:按照指定的码表把字节数组解码成字符串
编码 – 文字转换成数字的过程 文字转换成数字的规律 — 码表 ASCII (0-127 1个字节) — ISO8859-1 (西欧码表 0-255 1个字节) — GBK (国标码 2个字节) — Unicode编码体系 (UTF-8 3个字节, UTF-16 2个字节…)
所有的完整码表都默认兼容西欧码表
public class StringDemo6 { public static void main(String[] args) throws UnsupportedEncodingException { String str = "中文汉字123"; // 把字符串转成字节数组 -- 按指定的编码进行转换 // 以GBK进行编码 byte[] bs = str.getBytes("gbk"); // 指定编码方式 System.out.println(bs.length); // 11 // 以UTF-8进行解码,编码和解码的码表不一致会导致乱码 // String s = new String(bs); // 乱码 // 按照指定的码表进行解码把字符数组转成字符串 String s = new String(bs,"gbk"); System.out.println(s); // 中文汉字123 String s2 = new String(bs,0,8,"gbk"); System.out.println(s2); // 中文汉字 } }
hashCode()
:返回对象的哈希码值(重写方法只和字符串内容以及顺序有关系)
public class StringDemo7 { public static void main(String[] args) { String str1 = "abc"; String str2 = new String("abc"); // 如果两个对象的内容完全一致,哈希码值完全相同 // String类重写hashcode方法,整个计算过程之和字符串的内容和顺序相关 System.out.println(str1.hashCode()); System.out.println(str2.hashCode()); } }
indexOf(int ch)
:返回子串在原串中第一次出现的下标
indexOf(int ch, int fromIndex)
:返回从指定的起始下标(包含)开始往后查找第一次出现的下标
lastIndexOf(int ch)
:从后向前查找
public class StringDemo8 { public static void main(String[] args) { String str = "ajlksdjfgesdr"; // 返回子串在新串中第一次出现的下标值 // 没有找到下标时返回-1 System.out.println(str.indexOf("sd")); // 返回从指定的起始下标(包含)开始往后查找第一次出现的下标 System.out.println(str.indexOf("sd",5)); } }
intern()
:改变引用的指向,指向方法区
public class StringDemo8 { public static void main(String[] args) { String str1 = "abc"; String str2 = new String("abc"); str2 = str2.intern(); System.out.println(str1 == str2); // true } }
isEmpty()
:判断字符串是否是空串(没有内容的字符串)
public class StringDemo8 { public static void main(String[] args) { String str = ""; String str1 = new String(""); String str2 = new String(); System.out.println(str.isEmpty()); // true System.out.println(str1.isEmpty()); // true System.out.println(str2.isEmpty()); // true } }
matches(String regex)
:根据填入的正则语法对字符串进行匹配
正则表达式(Regular Expression):对字符串操作的一种逻辑公式,一般使用正则表达式对字符串进行匹配和过滤
语法:使用元字符进行排列组合来匹配字符串
元字符:具有固定含义的特殊符号
代码 | 说明 |
---|---|
. | 匹配除换行符以外的任意字符 |
\w | 匹配字母或数字或下划线 |
\s | 匹配任意的空白符 |
\d | 匹配数字 |
\n | 匹配一个换行符 |
\t | 匹配一个制表符 |
^ | 匹配字符串的开始 |
$ | 匹配字符串的结束 |
\W | 匹配非字母或数字或下划线 |
\D | 匹配非数字 |
\S | 匹配非空白字符 |
a|b | 逻辑或,匹配a或者b |
() | 匹配括号内的表达式,也表示一个组 |
[…] | 匹配字符组中的字符,如:[0-9a-zA-Z] |
[^…] | ^表示逻辑非,匹配除了字符组中字符的所有字符 |
量词:控制前面元字符出现的次数
代码 | 说明 |
---|---|
* | 重复0次或更多次 |
+ | 重复一次或更多次,如\d+(贪婪匹配) |
? | 重复0次或一次(出现或不出现) |
{n} | 重复n次 |
{n,} | 重复n次或更多次 |
{n,m} | 重复n-m次 |
public class PatternDemo1{ public static void main(String[]args){ Stringstr="hlakh4654sjklghkf"; //匹配字符串中有数字 //*用于控制前面的字符出现的个数(可以不出现也可以出现多次) System.out.println(str.matches(".*\\d.*")); } }
replaceAll(String regex, String replacement)
:根据填入的正则语法匹配所有符合条件的信息进行全部替换
public class StringDemo1 { public static void main(String[] args) { String str = "alskjd21345dshjlkhf"; // 根据正则语法进行匹配然后替换 // 去掉所有非数字信息 str= str.replaceAll("\\D",""); char [] cs= str.toCharArray(); Arrays.sort(cs); System.out.println(Arrays.toString(cs)); } }
split(String regex)
:根据正则语法匹配信息进行切割字符串,返回字符串数组
public class StringDemo2 { public static void main(String[] args) { String str = "akjfdal2354a6s5sa"; // 根据正则语法匹配的信息把字符串切割成字符串数组 // 匹配到的信息 --- 切割符(,) // 如果多个切割符出现在前面和中间,有多少个切割符会切出多少个',' // 如果切割符在末尾就会直接切掉 String ss[] = str.split("a"); // [, kjfd, l2354, 6s5s] System.out.println(Arrays.toString(ss)); } }
replace(CharSequence target, CharSequence replacement)
:根据新串的内容对原 串进行匹配和替换
public class StringDemo1 { public static void main(String[] args) { String str = "alskjd21345dshjlkhf"; System.out.println(str.replace("1","+")); } }
substring(int beginIndex)
:根据指定下标来截取字符串
public class StringDemo1 { public static void main(String[] args) { // 截取子串 String str1 = "alskjd21345dssfkhf"; // 截取 [3,end] System.out.println(str1.substring(3)); // 截取 [3,9) System.out.println(str1.substring(3,9)); } }
toString()
:重写toString()方法,为了输出时不再输出字符串对象的地址值而是输出字符串内容
trim()
:删除前面和后面的空白字符
public class StringDemo1 { public static void main(String[] args) { // 删除前后的空白字符 String str2 = " aksjd\tjlk sa4564aljkf\t"; System.out.println(str2.trim()); } }
valueOf()
: 可以支持任意类型数据转成String类型
public class StringDemo3 { public static void main(String[] args) { // 把boolean类型转为字符串类型 String s = String.valueOf(true); System.out.println(s); // 把int型转为字符串类型 String ss = String.valueOf(15); System.out.println(ss); int[] arr = {1,2,3}; char[] cs = {'4','5','干'}; // 底层默认通过valueOf()来调用Object类的toString方法来拼接地址值 System.out.println(arr); // 输出的是内容而不是地址值,底层默认没有传入到String类的valueOf()没有拼接地址值 System.out.println(cs); // 值 // 调用Object类中的toString方法拼接地址值 System.out.println(cs.toString()); // 地址值 } }
提供的大量方法返回的是新的字符串对象