String类及其常用方法
程序员文章站
2024-03-12 17:26:08
...
String类
JDK中内置的一个类:java.lang.String
(1)、String表示字符串类型,属于引用数据类型,不属于基本数据类型
(2)、在JDK当中,双引号括起来的字符串,例如:“abc” “des” “deg”都是直接存储在“方法区”的“字符串常量池”当中。
package javaCoreTest;
public class StringTest01 {
public static void main(String [] args) {
int i = 10;//i中保存10这个值
String s = "af";//s引用中保存的是“af"这个字符串的地址
//以下两行代码中一共创建了几个对象?
//一共3个对象:
//方法区字符串常量池中有1个“hello”
//堆内存当中有两个String对象
String s1 = "hello";
//"hello"是存儲在方法區的字符串常量池當中
//所以這個“hello"不會新建(因為這個對象已經存在了)
String s2 = "hello";
//分析結果是false還是true?
//==双等号比较的是变量中保存的内存地址
//但是此时s1、s2中的地址指向字符串常量池同一块空间,所以s1、s2当中的地址相同
System.out.println(s1 == s2);//true
String x = new String("xyz");
String y = new String("xyz");
//分析是true还是false?
//双等号比较的是变量中的内存地址
System.out.println(x == y);//false
//通过这个案例,我们知道,字符串对象之间的比较不能使用“==”
//“==”不保险,应该调用String类的equals方法
//String已经重写了equals方法
System.out.println(x.equals(y));//true
System.out.println("xyz".equals(y));//true
//建议使用“XXX”.equals(x)的形式调用equals方法,这样可以避免空指针异常
}
}
(3)、String为什么是不可变的?
我看过源代码,String类中有一个byte[]数组,这个byte[]数组采用了final修饰,因为数组一旦创建长度不可变,并且被final修饰的引用一旦指向某个对象之后,不可再指向其他对象,所以String是不可变的。
“ABC”无法变成“ABCD”
//字符串不可变是什么意思?
//是说双引号里面的字符串对象一旦创建不可变
String s = “abc”;//abc放到了字符串常量池当中。“abc”不可变
//s是可以指向其他对象的
s = “xyz”;//”xyz”被放到字符串常量池中,“xyz”不可变
(4)、StringBuilder/StringBuffer为什么是可变的呢?
我看过源代码,StringBuilder/StringBuffer内部实际上是一个byte[]数组,这个byte[]数组没有被final修饰,StringBuilder/StringBuffer的初始化容量我记得应该是16,当存满之后会进行扩容,底层调用了数组的拷贝方法System.arraycopy()是这样扩容的,所以StringBuilder/StringBuffer适合于使用字符串的频繁拼接操作。
package javaCoreTest;
/**
* 如果以后需要进行大量的字符串的拼接操作,建议使用JDK自带的:
* java.lang.StringBuffer
* java.lang.StringBuilder
*
* 如何优化StringBuffer的性能?
* 在创建StringBuffer的时候尽可能给定一个初始化容量
* 最好减少底层数组的扩容次数,预估一下,给一个大一些的初始化容量
* @author SKX
*
*/
public class StringBufferTest01 {
public static void main(String [] args) {
//创建一个初始化容量为16个byte[]数组(字符串缓冲区对象)
StringBuffer stringBuffer = new StringBuffer();
//拼接字符串:append()方法
stringBuffer.append("a");
stringBuffer.append("b");
stringBuffer.append("c");
stringBuffer.append(3.14);
stringBuffer.append(100L);
stringBuffer.append(true);
//append方法底层在进行追加的时候,如果byte数组满了,会自动扩容
System.out.println(stringBuffer.toString());//abc3.14100true
StringBuffer sb = new StringBuffer(100);
sb.append("courage");
sb.append("and");
sb.append("freedom");
System.out.println(sb);//courageandfreedom
}
}
package javaCoreTest;
/*
* java.lang.StringBuilder
* StringBuffer和StringBuilder的区别?
* StringBuffer中的方法都有synchronized关键字修饰,表示StringBuffer在多线程环境下运行是安全的。
* StringBuilder中的方法都没有synchronized关键字修饰,表示StringBuffer在多线程环境下运行是不安全的。
*
* StringBuffer 是线程安全的
* StringBuilder是非线程安全的
*/
public class StringBuilder01 {
public static void main(String [] args) {
//使用StringBuilder也是可以完成字符串的拼接
StringBuilder sb = new StringBuilder();
sb.append(100);
sb.append(true);
sb.append("hello");
sb.append("kitty");
System.out.println(sb);//100truehellokitty
}
}
package javaCoreTest;
/**
* 常用的String类的构造方法
* 第一种:String s = new String("");
* 第二种:String s = ""; //最常用
* 第三种:String s = new String(char[]);
* 第四种:String s = new String (char[], 起始下标, 长度);
* 第五种:String s = new String (byte[]);
* 第六种:String s = new String (byte[], 起始下标, 长度);
*/
public class StringTest02 {
public static void main(String [] args) {
byte [] bytes = {97, 98, 99};
//String构造方法:String(byte[] bytes)
String s1 = new String (bytes);
//String已经重写了toString方法,所以直接输出引用于调用toString方法的效果一样
System.out.println(s1);//abc
System.out.println(s1.toString());//abc
//提取指定位置、指定长度的字符串:String(字节数组,数组元素下标的起始位置,长度)
String s2 = new String (bytes, 1, 2);
System.out.println(s2);//bc
//将char数组全部转换成字符串:String(char[])
char[] chars = {'l', 'o', 'v', 'e'};
String s3 = new String(chars);
System.out.println(s3);//love
//将char数组定位定长转换成字符串:String(char[], 数组元素下标的起始位置,长度)
String s4 = new String(chars, 1, 2);
System.out.println(s4);//ov
}
}
package javaCoreTest;
/**
* String类当中的常用方法
* @author SKX
*
*/
public class StringTest03 {
public static void main(String [] args) {
//1.(掌握)char charAt(int index)
char c = "money".charAt(0);
System.out.println(c);//m
//2.(了解)int compareTo(String anotherString)
int result = "abc".compareTo("abc");
System.out.println(result);//0(等于0) 前后一致
int result1 = "abcd".compareTo("abce");
System.out.println(result1);//-1 (小于0) 前小后大
int result2 = "abce".compareTo("abcd");
System.out.println(result2);//1 (大于0) 前大后小
//3.(掌握)boolean contains(CharSequence s)
//判断前面的字符串中是否包含后面的子字符串
System.out.println("HelloWorld.java".contains(".java"));//true
System.out.println("http://www.baidu.com".contains("https://"));//false
//4.(掌握)boolean endsWith(String suffix)
//判断当前字符串是否以某个字符串结尾
System.out.println("text.txt".endsWith(".java"));//false
System.out.println("test.txt".endsWith(".txt"));//true
System.out.println("test.txt".endsWith("txt"));//true
//5.(掌握)boolean equals (Object anObject)
//比较两个字符串必须使用equals方法
System.out.println("avd".equals("avd"));//true
System.out.println("Avd".equals("avd"));//false
//6.(掌握)boolean equalsIgnoreCase(String anotherString)
//判断两个字符串是否相等,并且同时忽略大小写
System.out.println("Adv".equalsIgnoreCase("adv"));//true
//7.(掌握)byte[] getBytes()
//将字符串对象转换成字节数组
byte [] bt = "abcd".getBytes();
for(int i = 0; i < bt.length; i++) {
System.out.print(bt[i] + " ");//97 98 99 100
}
//8.(掌握)int indexOf(String str)
//判断某个子字符串在当前字符串中第一次出现处的索引
System.out.println("oraclejavac++.netc".indexOf("java"));//6
//9.(掌握)boolean isEmpty()
//判断某个字符串是否为空.底层调用的是字符串的length()方法
//空为true,非空为false
String s1 = "";
System.out.println(s1.isEmpty());//true
String s2 = " ";
System.out.println(s2.isEmpty());//false
//String s3 = null;
//System.out.println(s3.isEmpty());//java.lang.NullPointerException空指针异常
//10.(掌握)int length()
//面试题:判断数组长度和判断字符串长度不一样
//判断数组长度是length属性,判断字符串长度是length()方法
System.out.println("abc".length());//3
//11.(掌握)int lastIndexOf(String str)
//判断某个子字符串在当前字符串中最后一次出现的索引(下标)
System.out.println("oraclejavac++javac#phpjavapython".lastIndexOf("java"));//22
//12.(掌握)String replace(CharSequence target, CharSequence replacement)
//替换
String newString = "http://www.baidu.com".replace("http://", "https://");
System.out.println(newString);//https://www.baidu.com
//把以下字符串中的“=”替换成“:”
String newStr = "name=zhangsan&password=123&age=12".replace("=", ":");
System.out.println(newStr);//name:zhangsan&password:123&age:12
//13.(掌握)String[] split(String regex)
//拆分字符串
String[] ymd = "1980-12-30".split("-");//1980-12-30以“-”分隔符进行拆分
for(int i = 0; i < ymd.length; i++) {
System.out.print(ymd[i] + " ");//1980 12 30
}
System.out.println();
String [] person = "name=zhangsan&password=123&age=12".split("&");
for(int i = 0; i < person.length; i++) {
System.out.print(person[i] + " ");//name=zhangsan password=123 age=12
}
//14.(掌握)boolean startsWith(String prefix)
//判断某个字符串是否以某个子字符串开始
System.out.println("http://www.baidu.com".startsWith("http"));//true
System.out.println("http://www.baidu.com".startsWith("https"));//false
//15.(掌握)String substring(int beginIndex)//参数是起始下标
//截取字符串
System.out.println("http://www.baidu.com".substring(7));//www.baidu.com(包括起点)
//16.(掌握)String substring(int beginIndex, int endIndex)
//beginIndex起始位置包含
//endIndex结束位置不包含
System.out.println("http://www.baidu.com".substring(7, 10));//www(左闭右开)
//17.(掌握)char[] toCharArray()
//将字符串转换成char数组
char[] chars = "love".toCharArray();
for(int i = 0; i < chars.length; i++) {
System.out.println(chars[i]);
}
//18.(掌握)String toLowerCase()
//转换为小写
System.out.println("AGEEFVDdfdf".toLowerCase());//ageefvddfdf
//19.(掌握)String toUpperCase()
//转换为大写
System.out.println("svdjidJKN".toUpperCase());//SVDJIDJKN
//20.(掌握)String trim()
//去除字符串前后空白
System.out.println(" hello world ".trim());//hello world
//21.(掌握)String 中只有一个方法是静态的,不需要new对象
//这个方法叫做valueOf
//作用:将“非字符串”转换成“字符串”
String ss1 = String .valueOf(true);
System.out.println(ss1);
String ss2 = String .valueOf(100);
System.out.println(ss2);
String ss3 = String .valueOf(3.14);
System.out.println(ss3);
}
}
下一篇: 一個有意思的rake脚本
推荐阅读