这里写目录标题
一、字符串不可变
字符串是一种不可变对象,它的内容不可改变
String类的所有方法,只要返回值与原字符串不同,一定是一个新的对象(new String)
二、字符串的构造
String str="青科大";
String str1=new String("青科大");
char[] chars={'青','科','大'};
String str3=new String(chars);
三、字符串常量池
1、字符串的地址
在JVM底层实际上会自动维护一个对象池(字符串常量池)
字符串常量池中存放字符串常量值和字符串常量值的引用
所有字符串常量值都存放在字符串常量池中,且不会存相同的常量值
比较引用(str1==str2)比较的是地址
String str1="hello";
String str2=new String("hello");
System.out.println(str1==str2);
String str3="he"+"llo";//两个常量值相加,编译器认为它等同于 String str3="hello"
System.out.println(str1==str3);
String str4="he";
String str5="llo";
String str6=str4+str5;//两个变量相加
System.out.println(str1==str6);
String str7="he"+new String("llo");
System.out.println(str1==str7);
2、手动入池
String类的普通方法
public native String intern()
str.intern()
- 不需要赋值,如果在字符串常量池中发现有str的常量值,不再入池
如果没有,手动入池,引用入池 - 需要赋值,池中有,把它的引用给这个引用变量
如果没有,手动入池,把它的引用给这个引用变量
String str9=new String("德玛西亚");
str9=str9.intern();
String str10="德玛西亚";
System.out.println(str9==str10);
//手动入池
String str3=new String("qixi").intern();
// 等同于
// String str3=new String("qixi");
// str3=str3.intern();
String str4="qixi";
System.out.println(str3==str4);
String str5=new String("nuegou");
String str6="nuegou";
//此代码无效了
str5.intern();
System.out.println(str5==str6);
String str7=new String("科")+new String("大");
str7.intern();
String str8="科大";
System.out.println(str7==str8);
四、String类的方法
1、字符和字符串
字符和字符串 | |
---|---|
public String (char value[]) | 构造方法 将字符数组中的所有内容变成字符串 |
public String(char value[],int offset,int count) | 构造方法 部分字符数组转成字符串, offset–开始位置,count–个数 |
public char charAt(int index) | 取得指定索引位置的字符 |
public char[ ] toCharArray() | 将字符串变为字符数组返回 |
char[] chars={'青','科','大','欢','迎','你'};
String str=new String(chars);
System.out.println(str);
String str1=new String(chars,1,5);
System.out.println(str1);
char ch=str.charAt(0);
System.out.println(ch);
char[] chars1=str.toCharArray();
System.out.println(Arrays.toString(chars1));
判断字符串是否只有数字
public static boolean isNumber2(String str2){
for (int i = 0; i <str2.length() ; i++) {
char ch=str2.charAt(i);
if(ch<'0'||ch>'9'){
return false;
}
}
return true;
}
public static boolean isNumber(String str2){
char[] chars2=str2.toCharArray();
// for (int i = 0; i <chars2.length ; i++) {
// if(chars2[i]<'0'||chars2[i]>'9'){
// return false;
// }
// }
for (char ch:chars2) {
if(ch<'0'||ch>'9'){
return false;
}
}
return true;
}
2、字节与字符串
字节与字符串 | |
---|---|
public String (byte bytes[ ]) | 构造方法 将字节数组转变成字符串 |
public String(byte bytes[ ] , int offset , int length ) | 构造方法 将部分字节数组中的内容变为字符串 |
public byte[ ] getBytes( ) | 将字符串以字节数组的形式返回 |
public byte[ ] getBytes(String charsetName )throws UnsupportedEncodingException | 编码转换处理 charsetName 字符编码 utf-8 或 GBK |
public static void main(String[] args) throws UnsupportedEncodingException {
byte[] bytes={97,98,99};
String str=new String(bytes);
System.out.println(str);
String str1=new String(bytes,1,2);
System.out.println(str1);
String str2="abcdefg";
byte[] bytes1=str2.getBytes();
System.out.println(Arrays.toString(bytes1));
String str3="德玛西亚";
//发生编译时异常,用Alt+回车 添加 throws
// UnsupportedEncodingException
byte[] bytes2=str3.getBytes("utf-8");
System.out.println(Arrays.toString(bytes2));
}
3、字符串比较
字符串比较 | |
---|---|
public boolean equals(Object anObject) | 区分大小写的比较 |
public boolean equalsIgnoreCase( String anotherString) | 不区分大小写的比较 |
public int compareTo(String anotherString) | 比较两个字符串大小关系比较字母,返回差值(ASCLL码) |
String str1 = "abc";
String str2 = "ABc";
System.out.println(str1.equals(str2));
System.out.println(str1.equalsIgnoreCase(str2));
//差值是第一个字符的差值
如果第一个字符相同,则是第二个字符比较的差值
System.out.println(str1.compareTo(str2));
4、字符串查找
字符串查找 | |
---|---|
public boolean contains(CharSequence s) | 判断一个子字符串是否存在 |
public int indexOf(String str) | 从头开始查找指定字符串的位置,查到了返回位置的开索引,如果查不到,返回-1 |
public int indexOf(String str , int fromIndex) | 从指定位置开始查找子字符串 |
public int lastIndexOf(String str ) | 从后往前查找指定子字符串位置,返回位置的开始索引 |
public int lastIndexOf(String str , int fromIndex) | 从指定位置,由后向前查找子字符串 |
public boolean startsWith(String prefix) | 判断是否以指定字符串开头 |
public boolean startsWith(String prefix , int toffset) | 从指定位置开始判断是否以指定字符串开头 |
public boolean endsWith(String suffix) | 判断是否以指定字符串结尾 |
String str="abcabcd";
boolean a=str.contains("cd");
System.out.println(a); // true
int a2=str.indexOf("cd");
System.out.println(a2); // 5
// 指定位置也算,指定位置是从 0---str.length()-1
int a3=str.indexOf("bc",1);
System.out.println(a3); // 1
int a4=str.lastIndexOf("bc");
System.out.println(a4); // 4
// 从指定位置开始,由后向前查找,指定位置也算
int a5=str.lastIndexOf("ab",4);
System.out.println(a5); // 3
boolean a6=str.startsWith("abc");
System.out.println(a6); // true
boolean a7=str.startsWith("bc",3);
System.out.println(a7); // false
boolean a8=str.endsWith("ad");
System.out.println(a8); // false
5、字符串替换
字符串替换 | |
---|---|
public String replaceAll(String regex , String replacement) | 替换所有的指定内容;regex 需要替换的内容;replacement 接收的内容 |
public String replaceFirst(String regex , String replacement) | 替换首个内容 |
String str="abcabcabff";
String ret=str.replaceAll("ab","A");
System.out.println(ret); // AcAcAff
String ret1=str.replaceFirst("abc","P");
System.out.println(ret1); // Pabcabff
}
6、字符串拆分
字符串拆分 | |
---|---|
public String[ ] split(String regex) | 将字符串按regex为界全部拆分 |
public String[ ] split(String regex , int limit) | 将字符串部分拆分,该数组的长度就是limit |
public static void main1(String[] args) {
String str = "青科大 欢迎 兄弟们";
String[] ret = str.split(" ", 2);
for (String a : ret) {
System.out.println(a);
}
String str1 = "196.25.32.1";
//识别不了反斜杠,转义字符\\ 表示\
String[] ret1 = str1.split("\\.");
for (String b : ret1) {
System.out.println(b);
}
// \25、\32、\1容易被当成八进制了
String str3 = "196\25\32\1";
//此处的"\\" 代表 "\"
String str2 = "196\\25\\32\\1";
System.out.println(str2)
String[] ret2 = str2.split("\\\\");
for (String c : ret2) {
System.out.println(c);
}
String str4 = "欢迎&到青岛||喝啤酒#吃蛤蜊";
String[] ret3 = str4.split("&|\\|\\||#");
for (String e : ret3) {
System.out.println(e);
}
System.out.println("======================================");
//逐层分
String str5 = "欢迎&大家*到青科大&干饭";
String[] ret4 = str5.split("\\*");
for (String ss : ret4) {
// System.out.println(ss);
String[] ret5 = ss.split("&");
for (String s : ret5) {
System.out.println(s);
}
}
}
1、字符 " | " 、 " * " 、 " + " 、 " . " 、" \ " 都要加上转义字符
2、" \ " 表示为 " \\" " \\ "表示为 " \\\\ "
3、如果一个字符串中有多个分隔符,可以用" | "作为连字符
7、字符串截取
字符串截取 | |
---|---|
public String substring(int beginIndex) | 从指定索引截取到结尾 |
public String substring(int beginIndex , int endIndex) | 前闭后开[ begin ,end ) |
public static void main(String[] args) {
String str = "abcabcabcmn";
System.out.println(str.substring(2)); // cabeabf
//[2,5) 左闭右开
System.out.println(str.substring(2, 5)); // cab
}
8、其他操作方法
均为普通方法
其他操作方法 | |
---|---|
public String trim() | 去掉字符串中的左右空格,保留中间的空格 |
public String toUpperCase() | 字符串转大写 |
public String toLowerCase() | 字符串转小写 |
Public boolean isEmpty() | 判断是否为空字符串,但不是null,是长度为0 |
String str=" Love You ";
System.out.println(str.trim());
System.out.println(str.toUpperCase());
System.out.println(str.toLowerCase());
}
五、 StringBuffer和Stringbuilder
String的加号拼接,会被底层优化为一个StringBuilder,频繁修改字符串的情况考虑使用StringBuilder
1、String和StringBuider及StringBuffer的区别
- String的内容无法修改,StringBuilder和StringBuffer的内容可以修改
- String的拼接会产生临时对象,但是StringBuilder和StringBuffer的拼接每次都只是返回当前对象的引用(不会产生临时对象,拼接的自始至终是一个对象)
public static void main5(String[] args) {
StringBuffer str = new StringBuffer("qust");
str.append("er");
str.append("666");
System.out.println(str); // quster666
String str1 = "abc";
String str2 = "def";
String str3 = str1 + str2;
// 等同于
// StringBuffer sb = new StringBuffer();
// sb.append(str1);
// sb.append(str2);
// String str3 = sb.toString();
System.out.println(str3); // abcdef
}
2、Stringbuilder和StringBuffer的区别
- public synchronized StringBuffer append(String str)
synchronized 相当于一把锁,在多线程情况下,保证线程安全 - public Stringbuilder append(String str)
StringBuilder和String一般不涉及多线程使用
StringBuffer采用同步处理,属于线程安全操作;而StringBuilder未采用同步处理,属于线程不安全操作
3、Stringbuffer和String的转变
Stringbuffer------>String | 调用toString()方法 |
String -------->StringBuffer | 利用StringBuffer的构造方法或append()方法 |
4、Stringbuffer相对于String特有的方法
public synchronized StringBuffer reserve() | 字符串反转 |
public synchronized StringBuffer delete(int start , int end) | 删除数据,前闭后开 |
public synchronized StringBuffer insert(int offset , 各种数据类型 b) | 插入数据 |
六、例题
1、字符数组中的字符拼接起来是否相等
public static void main(String[] args) {
String[] word1 = {"ab", "a", "as"};
String[] word2 = {"a", "d", "c"};
System.out.println(arrayStringsAreEqual(word1,word2));
}
public static boolean arrayStringsAreEqual(String[] word1,
String[] word2) {
if(word1==null&&word2==null){
return true;
}
if(word1==null||word2==null){
return false;
}
if(word1.length==0&&word2.length==0){
return true;
}
if(word1.length==0||word2.length==0){
return false;
}
StringBuilder wordA = new StringBuilder();
StringBuilder wordB = new StringBuilder();
for (int i = 0; i <word1.length ; i++) {
wordA.append(word1[i]);
}
for (int i = 0; i <word2.length ; i++) {
wordB.append(word2[i]);
}
if((wordA.toString()).equals(wordB.toString())){
return true;
}
return false;
}
2、形如 "abc bcd bdf"的字符串转变为 “abcbcdbdf”
public static void main2(String[] args) {
Scanner scanner = new Scanner(System.in);
//ctrl+D 结束
while (scanner.hasNextLine()) {
String str = scanner.nextLine();
String[] ret = str.split(" ");
StringBuilder a= new StringBuilder();
for (String b : ret) {
a.append(b);
}
System.out.println(a);
}
}
3、反转字符串 “abc” ---->“cba”
public static String reserve(String str) {
if (str == null) {
return null;
}
char[] chars = str.toCharArray();
int i = 0;
int j = chars.length - 1;
while (i < j) {
char temp = chars[i];
chars[i] = chars[j];
chars[j] = temp;
i++;
j--;
}
return new String(chars);
}
4、“abcdef” ---->“defabc”
public static String reserve(String str, int start, int last) {
char[] chars = str.toCharArray();
while (start < last) {
char temp = chars[start];
chars[start] = chars[last];
chars[last] = temp;
start++;
last--;
}
return new String(chars);
}
public static String reserveSentence(String str, int n) {
if (str == null) {
return null;
}
if (str.length() == 0) {
return null;
}
int last1 = n - 1;
int last2 = str.length() - 1;
str = reserve(str, 0, last1);
str = reserve(str, n, last2);
str = reserve(str, 0, last2);
return str;
}