基础
String能存字符串的本质是类中包装了一个数组。
String类JDK1.9比1.8增多,从1.9开始,string中的数组是byte(字节)数组;1.8以前是char(字符)数组。
实例化有两种形式,直接赋值,动态赋值。
String如果用new赋值,==比较失效,因为两个字符串分别是两个对象,只能用equals进行比较。如果直接赋值,例如 String a = “111”,String b = “111”,a==b返回为true。
字符串常量是String类的匿名对象。
判断匿名对象是否存在:
String str = "111";
System.out.println("111".equals(str));//返回值为true
String字符串池
JDK1.7 及之后版本的 JVM 已经将运行时常量池从方法区中移了出来,在 Java 堆(Heap)中开辟了一块区域存放运行时常量池。
使用直接赋值会放到字符串池中,每次创建新的String匿名对象时会先去字符串池中寻找是否已经创建,所以String的匿名对象可以用 == 比较。
动态赋值(创建对象)会生成新的空间,每次创建的String对象都不在同一字符串池中。但是可以用intern方法放入到字符串池中。
String str = "111";
String str2 = new String("111").intern();
System.out.println(str == str2);//返回值为true
以String对象池为例,对象池(常量池)的主要目的是实现数据的共享处理,主要分为静态常量池和运行时常量池。
静态常量池指程序在加载时会自动的将此程序之中保存的字符串、常量、类和方法等等,全部进行分配。
运行时常量池是指当一个程序加载之后,里面可能有一些变量,这个时候提供的常量池。
静态常量池:
String str = "11";
String str2 = "1" + "1";
System.out.println(str == str2);//return true
运行时常量池:
String str = "11";
String test = "1";
String str2 = "1" + test;
System.out.println(str == str2);//return false 创建 StringBuilder 对象,然后调用 append 方法
常量池综合整理:
package com.yue.String;
public class StringTest {
public static void main(String[] args) {
String s1 = "a";
String s2 = "b";
String s3 = "ab";
String s4 = "ab";
String s5 = "a" + "b";
String s6 = s1+s2;
String s7 = new String("ab");
final String s8 = "a" ;
final String s9 = "b" ;
String s10 = s8 + s9;
// s3与s4根据String的概念他们都指向了同一个缓冲池内的地址,所以结果为true
System.out.println("s3==s4? "+ (s3==s4));
// s3与s5因为相加的两个为常量所以编译器会把s5="a"+"b"优化为s5="ab"。所以结果也为true。
System.out.println("s3==s5? "+ (s3==s5));
/*
* s3与s6因为是两个变量的相加所以编译器无法优化,
* s1+s2即等同于(new StringBuilder(String.valueOf(s1))).append(s2).toString();
* 在运行时,会有新的String地址空间的分配,而不是指向缓冲池中的“ab”。所以结果false。
*/
System.out.println("s3==s6? "+ (s3==s6));
/*
* s3与s7,根据缓冲池的定义在new的时候实际会新分配地址空间,
* s7指向的是新分配的地址空间所以与缓冲池地址不同,所以为false
*/
System.out.println("s3==s7? "+ (s3==s7));
// s3与s10,类似于s3与s5,因为是final类型编译器进行了优化所以相同。
System.out.println("s3==s10? "+ (s3==s10));
}
}
toCharArray()方法,用于判断字符串内每一个字符。
public boolean isNumber(String s){
char []result = s.toCharArray();//将字符串变为字符数组
for(int x = 0; x < result.length; x++){
if(result[x]<'0'|| result[x]>'9'){
return false;
}
return true;
}
字符串比较
1.equals -> 区分大小写的相等判断
2.equalsIgnoreCase -> 不区分大小写的相等判断
3.compareTo->进行字符串大小比较,返回值是Int,大于返回大于几,小于返回小于几
4.compareToIgnoreCase->不区分大小写进行字符串大小比较
字符串查找
1.contains->判断字符串是否存在
2.indexOf->从头(指定位置)查找指定字符串位置
3.lastIndexOf->从后(指定位置)查找字符串位置
判断开头结尾: startwith/endwith
String str = "11aaa22";
System.out.println(str.startwith("11"));
System.out.println(str.endwith("22"));
字符串替换
1.replaceAll->全部替换
2.replaceFirst->替换首个
字符串拆分
split->按照指定的字符串全部拆分(指定个数拆分)
String a = "AAA BBB CCC";
String []res = a.split(" ");
for (String s:res) {
System.out.println(s);
}
/*
AAA
BBB
CCC
*/
String []res2 = a.split(" ", 2);
for (String s:res2) {
System.out.println(s);
}
/*
AAA
BBB CCC
*/
字符串截取
substring->从指定索引截取到结尾(指定位置)
String a = "10010-pic-wangyue.jpg";
int begin = a.indexOf("-",a.indexOf("pic"))+1;
int end = a.lastIndexOf(".");
System.out.println(a.substring(begin, end));
通过索引确定指定字符串。
格式化字符串
类似C语言:字符串(%s) 、字符(%c)、整数(%d)、小数(%f)
format->根据指定的结构进行文本显示
其他方法
concat->连接字符串
String a = "111";
String b = "1".concat("1").concat("1");// b = "111"
String c = "1"+"1"+"1" ;
System.out.println(a == b); //false -> 此操作结果一样但是并不是一个静态的变化
System.out.println(a == c); //true -> 证明了concat与+ 不同
trim->去空格
length->计算字符串长度
toUpperCase -> 转大写
toLowerCase -> 转小写
自定义首字母大写的方法:
class StringUtil{
public static String initCap(String str){
if(str == null || str.equals("")){
return str;
}
if(str.length() == 1){
return str.toUpperCase();
}
return str.substring(0,1).toUpperCase() + str.substring(1);
}
}