8、String类的特点及使用
JDK_API文档由下面几部分组成:
(1)类的定义以及相关的继承结构
(2)类的简短说明
(3)类的成员组成
(4)类所提供的构造方法
(5)类所提供的普通方法
(6)类的成员,构造方法,普通方法的详细说明deprecated
标记表示不再建议使用。
String对象的两种实例化方式
1.String
是字符串类,下面将类的角度与内存关系分析其作用:
(1)直接赋值String value_name = "字符串"
public class Demo {
public static void main(String[] args) {
String str = "Hello World !"; // 直接赋值
System.out.println(str);
}
}
(2)构造方法public String (String str);
public class Demo {
public static void main(String[] args) {
String str = new String("Hello World !");
System.out.println(str);
}
}
字符串比较
1.判断两个int数据是否相等:
public class Demo {
public static void main(String[] args) {
int x = 10;
int y = 10;
System.out.println(x == y); // true
}
}
使用==
判断String对象是否相等:
public class Demo {
public static void main(String[] args) {
String strA = "Hello";
String strB = new String("Hello");
String strC = strB;
System.out.println(strA == strB); // false
System.out.println(strA == strC); // false
System.out.println(strB == strC); // true
}
}
对上述代码进行内存分析:
由内存分析可知,String对象使用==
比较时,比较的是对象的栈内存地址的值。
2.要比较字符串的内容,应使用String类中的方法public boolean equals(String str)
public class Demo {
public static void main(String[] args) {
String strA = "Hello";
String strB = new String("Hello");
String strC = strB;
System.out.println(strA.equals(strB)); // true
System.out.println(strA.equals(strC)); // true
}
}
开发中,字符串比较应用equals(String str)
.
3.章节例题:==
与equals(String str)
的区别==
是关系运算符,用于判断数值相等,当用于String对象时对比的是两个对象的栈内存地址的值;equals(String str)
是String类的方法,用于比较字符串内容。
String常量是匿名对象
1.编程语言中没有字符串概念,很多语言使用字符数组描述字符串。Java开发由于离不开字符串的使用,便创造了字符串,但不属于基本数据类型,而是将字符串作为String类的匿名对象。
范例:验证字符串是匿名对象
public class Demo {
public static void main(String[] args) {
String str = "Hello";
System.out.println("Hello".equals(str));
}
}
2.直接赋值的方式相当于给匿名对象设置了对象名,区别是String匿名对象是系统自动生成,不需要由用户实例化.
public class Demo {
public static void main(String[] args) {
String input = null; // 假设该内容是用户输入的
if (input.equals("hello")){
System.out.println("Hello World !");
// 报错,NullPointerException
}
}
}
为预防用户输入错误导致input为null,而后调用equals()
,出现空指针异常,应使用如下代码:
public class Demo {
public static void main(String[] args) {
String input = null; // 假设该内容是用户输入的
if ("hello".equals(input)){
System.out.println("Hello World !");
}
}
}
使用上述代码将不会出现空指针异常,因此在判断用户输入的内容是否符合预期时,应将指定字符串放在equals()前。
两种实例化方式的区别
1.直接赋值
直接赋值就是给字符串匿名对象设置对象名。
此时内存中会开辟堆内存,并且有一块栈内存指向堆内存:
观察下列代码:
public class Demo {
public static void main(String[] args) {
String strA = "hello";
String strB = "hello";
String strC = "hello";
String strD = "world";
System.out.println(strA == strB); // true
System.out.println(strA == strC); // true
System.out.println(strB == strC); // true
System.out.println(strA == strD); // false
}
}
由上述结果可知,strA,strB,strC都指向同一块堆内存:
共享设计模式:JVM底层存在一个对象池,保存有对象。当使用直接赋值定义String对象时,会将该对象使用的匿名对象入池保存。而后如果有其他String对象也采用直接赋值方式且内容相同时,便不再开辟新的堆内存,而是引用对象池中已有的匿名对象。
2.构造方法实例化
使用构造方法定义String对象,就需要每次开辟新的堆内存。
由内存分析可知,使用构造方法实例化时开辟了两块堆内存,并且其中一块会成为垃圾。
public class Demo {
public static void main(String[] args) {
String strA = new String("hello");
String strB = "hello";
System.out.println(strA == strB); // false
}
}
除了内存的浪费外,使用构造方法定义的String对象,其内容不会保存在对象池中,因为每次开辟的都是新的堆内存。如果希望开辟的新的的堆内存也进入对象池保存,可以使用public String intern()
手工入池。
3.章节小题:String对象两种定义方式的区别
· 直接赋值只开辟一块堆内存,且会自动保存在对象池中,以便下次使用;
· 构造方法赋值会开辟两块堆内存,其中一块会成为垃圾,不会自动入池,但可以使用”intern()”手工入池。
字符串内容不可改变
public class Demo {
public static void main(String[] args) {
String str = "Hello";
str += " World";
str += " !!!";
System.out.println(str);
}
}
对上述代码进行内存分析:
分析后可知,字符串内容并未改变(Java规定String对象内容不可变),字符串内容的变动实际是引用关系的变化,每次都会出现垃圾。因此字符串内容不要频繁改动。
String类常用方法(字符与字符串)
很多语言利用字符数组描述字符串,Java中String类的方法也有相似方法:
No. | 方法名称 | 类型 | 描述 |
---|---|---|---|
1 | public String (char[] value) | 构造 | 将字符数组变为String类对象 |
2 | public String (char[] value ,int offset,int count) | 构造 | 将部分字符数组变为String对象 |
3 | public char charAt (int index) | 普通 | 返回指定索引对应的字符信息 |
4 | public char[] toCharArray() | 普通 | 将字符串以字符数组的形式返回 |
范例:取出指定索引的字符
public class Demo {
public static void main(String[] args) {
String str = "Hello";
char c = str.charAt(0);
System.out.println(c); // H
}
}
范例:将字符串转大写
public class Demo {
public static void main(String[] args) {
String str = "hello";
char [] data = str.toCharArray(); // 字符串转为字符数组
for (int x = 0; x < data.length ; x++) {
data[x] -= 32; // 小写编码 - 32 = 大写编码
}
// 将字符数组变为字符串
System.out.println(new String(data)); // HELLO
// 将部分字符数组变为String对象
System.out.println(new String(data, 1, 2)); // EL
}
}
范例:判断一个字符换是否为纯数字
思路:对字符串整体进行判断是无法实现的,但是可以将字符串转为字符数组,判断每一个字符是否为数字。
public class Demo {
public static void main(String[] args) {
String str = "3146017052";
if (isNumber(str)) {
System.out.println("字符串全部由数字组成");
} else {
System.out.println("字符串不是全部由数字组成");
}
}
// 定义判断字符串是否由数字组成的方法
public static boolean isNumber(String temp) {
// 首先将字符串变为字符数组
char[] data = temp.toCharArray();
// 一一比较字符
for (int x = 0; x < data.length; x++) {
if (data[x] > '9' || data[x] < '0') {
return false;
}
}
// 全部为数字则返回true
return true;
}
}
建议:返回值为boolean
的方法命名为isXxx
。
String类常用方法(字节与字符串)
字节使用byte描述,一般用于数据传输或编码转换。String提供了将字符数组变为字节数组的方法。
No. | 方法名称 | 类型 | 描述 |
---|---|---|---|
1 | public String (byte[] bytes) | 构造 | 将字节数组变为字符串 |
2 | public String (byte[] bytes ,int offset,int length) | 构造 | 将部分字节数组变为字符串 |
3 | public byte[] getBytes (String charsetName) throws UnsupportedEncodingException | 普通 | 进行编码转换 |
4 | public byte[] getBytes() | 普通 | 将字符串变为字节数组 |
范例:字符串与字节数组的转换
public class Demo {
public static void main(String[] args) {
String str = "helloworld";
byte [] data = str.getBytes(); // 将字符串转为字节数组
for (int x = 0; x < data.length ; x++) {
data[x] -= 32; // 将小写字母转为大写字母
}
System.out.println(new String(data)); // HELLOWORLD
System.out.println(new String(data,5,5)); // WORLD
}
}
String类常用方法(字符串比较)
No. | 方法名称 | 类型 | 描述 |
---|---|---|---|
1 | public boolean equals(String anotherString) | 普通 | 进行内容判断,区分大小写 |
2 | public boolean equalsIgnoreCase(String anotherString) | 普通 | 进行内容判断,不区分大小写 |
3 | public int compareTo (String anotherString) | 普通 | 判断两个字符串的大小(按照字符编码),返回值为0,1,-1 |
范例:equals()判断
public class Demo {
public static void main(String[] args) {
String strA = "Hello";
String strB = "hello";
System.out.println(strA.equals(strB)); // false,说明区分大小写
}
}
范例:equalsIgnoreCase()判断
public class Demo {
public static void main(String[] args) {
String strA = "Hello";
String strB = "hello";
System.out.println(strA.equals(strB)); // false,说明区分大小写
System.out.println(strA.equalsIgnoreCase(strB)); // true,说明不区分大小写
}
}
范例:compareTo()
public class Demo {
public static void main(String[] args) {
String strA = "Hello";
String strB = "hello";
System.out.println(strA.compareTo(strB)); // -32
if (strA.compareTo(strB) > 0){
System.out.println("大于");
} else if (strA.compareTo(strB) == 0){
System.out.println("两个字符串相等");
} else {
System.out.println("小于");
}
}
}
只有String对象才能进行大小判断。
String类常用方法(字符串查找)
要判断指定内容的字符串是否存在于一个字符串中,可使用如下方法:
No. | 方法名称 | 类型 | 描述 |
---|---|---|---|
1 | public boolean contains (String s) | 普通 | 判断指定内容是否存在 |
2 | public int indexOf(String s) | 普通 | 由前向后查找指定字符串的位置,找到后返回首字母索引,未找到,返回-1。 |
3 | public int indexOf(String s,int fromIndex) | 普通 | 从指定索引由前向后查找指定字符串的位置,找到后返回首字母的索引。未找到,返回-1 |
4 | public int lastindexOf(String s) | 普通 | 由后向前查找指定字符串的位置,找到后返回首字母的索引,如果找不到,返回-1 |
5 | public int lastindexOf(String s, int fromIndex) | 普通 | 由后向前从指定位置查找指定字符串的位置,找到后返回首字母的索引,如果找不到,返回-1 |
6 | public boolean startsWith (String prefix) | 普通 | 判断是否以指定字符串开头 |
7 | public boolean startsWith (String prefix,int toffset) | 普通 | 从指定位置开始判断是否是以指定字符串开头 |
8 | public boolean endsWith(String suffix) | 普通 | 判断是否以指定字符串结尾 |
范例:查找字符串位置
public class Demo {
public static void main(String[] args) {
String str = "helloworld";
// 返回满足条件的单词的首字母索引
System.out.println(str.indexOf("world")); // 5,为w的索引
// 从索引5开始查满足条件单词的索引
System.out.println(str.indexOf("l",5)); // 8
// 从后向前查
System.out.println(str.lastIndexOf("l")); // 8
}
}
在某些程序中,需要查找指定字符串是否存在,早期方法如下:
public class Demo {
public static void main(String[] args) {
String str = "helloworld";
if (str.indexOf("world") != -1){
System.out.println("该字符串存在");
} else {
System.out.println("该字符串不存在");
}
}
}
JDK1.5出现contains()
,使用如下:
public class Demo {
public static void main(String[] args) {
String str = "helloworld";
if (str.contains("world")) {
System.out.println("该字符串存在");
} else {
System.out.println("该字符串不存在");
}
}
}
范例:开头或结尾判断内容
public class Demo {
public static void main(String[] args) {
String str = "helloworld";
// 从开头开始查
System.out.println(str.startsWith("he"));
// 从索引2开始查找
System.out.println(str.startsWith("ll",2));
// 从结尾开始查找
System.out.println(str.endsWith("ld"));
}
}
String类常用方法(字符串替换)
No. | 方法名称 | 类型 | 描述 |
---|---|---|---|
1 | public String replaceAll(String regex,String replacement) | 普通 | 全部替换 |
2 | public String replaceFirst(String regex,String replacement) | 普通 | 替换首个满足条件的内容 |
public class Demo {
public static void main(String[] args) {
String str = "helloworld";
// 替换所有
String resultA = str.replace("l","_"); // he__owor_d
// 只替换第一个
String resultB = str.replaceFirst("l","_"); // he_loworld
System.out.println(resultA);
System.out.println(resultB);
}
}
String类常用方法(字符串截取)
No. | 方法名称 | 类型 | 描述 |
---|---|---|---|
1 | public String substring(int beginIndex) | 普通方法 | 从指定索引截取到结尾 |
2 | public String substring(int beginIndex,int endIndex) | 普通方法 | 截取指定范围内的内容 |
public class Demo {
public static void main(String[] args) {
String str = "helloworld";
// 从索引5开始截取直到结尾
String resultA = str.substring(5);
// 截取索引5到8之间
String resultB = str.substring(5,8);
System.out.println(resultA); // world
System.out.println(resultB); // wor
}
}
String类常用方法(字符串拆分)
No | 方法名称 | 类型 | 描述 |
---|---|---|---|
1 | public String[] split (String regex) | 普通方法 | 按照指定的字符串进行全部拆分 |
2 | public String[] split (String regex,int limit) | 普通方法 | 按照指定的字符串进行部分拆分,最后一个数组长度由limit决定 |
范例:全部拆分
public class Demo {
public static void main(String[] args) {
String str = "hello world";
// 按照空格拆分单词
String result[] = str.split(" ");
for (int x = 0; x < result.length; x++) {
System.out.println(result[x]);
// 结果:hello
// world
}
}
}
在拆分的时候,只写一个空字符串(""
不是null
),表示按照每一个字符进行拆分。
public class Demo {
public static void main(String[] args) {
String str = "hello world";
// 按照空字符串拆分
String result[] = str.split("");
for (int x = 0; x < result.length; x++) {
System.out.println(result[x]);
// 结果:h e l l o w o r l d
}
}
}
范例:部分拆分
public class Demo {
public static void main(String[] args) {
String str = "hello world nihao mldn";
// 把字符串按空格拆成3个,前2个拆完后,后面的不再按空格拆
String result[] = str.split(" ",3);
for (int x = 0; x < result.length; x++) {
System.out.println(result[x]);
// 结果:"hello" "world" "nihao mldn"
}
}
}
范例:IP地址拆分
public class Demo {
public static void main(String[] args) {
String str = "192.168.1.1";
String result[] = str.split("\\.");
for (int x = 0; x < result.length; x++) {
System.out.println(result[x]);
// 结果为:192 168 1 1
}
}
}
上述代码中,只用.
无法拆分,当遇到这种拆分时,需要使用\\.
进行转义后拆分。
范例:拆分“张三:20|李四:25|王五:23”
public class Demo {
public static void main(String[] args) {
String str = "张三:20|李四:25|王五:23";
String result[] = str.split("\\|");
for (int x = 0; x < result.length; x++) {
String temp[] = result[x].split(":");
System.out.println("姓名:" + temp[0] + ",年龄" + temp[1]);
}
}
}
String类其他方法
No. | 方法名称 | 类型 | 描述 |
---|---|---|---|
1 | public String concat (String str) | 普通方法 | 字符串连接 |
2 | public String toLowerCase () | 普通方法 | 把字符串转为小写 |
3 | public String toUpperCase () | 普通方法 | 把字符串转为大写 |
4 | public String trim () | 普通方法 | 去掉字符串中左右两边的空格,中间空格保留 |
5 | public int length() | 普通方法 | 取得字符串长度 |
6 | public String intern () | 普通方法 | 数据入池操作 |
7 | public boolean isEmpty () | 普通方法 |
范例:字符串连接
public class Demo {
public static void main(String[] args) {
String strA = "hello";
String strB = strA + " world";
String strC = "hello" + "world";
String strD = "hello world";
String strE = strA.concat(" world");
System.out.println(strB == strC); // false
System.out.println(strB == strD); // false
System.out.println(strB == strE); // false
System.out.println(strC == strD); // false
System.out.println(strC == strE); // false
System.out.println(strD == strE); // false
}
}
范例:字符串进行大小写转换
public class Demo {
public static void main(String[] args) {
String str = "*Hello*";
// 只转换小写字母
System.out.println(str.toUpperCase()); // *HELLO*
// 只转换大写字母
System.out.println(str.toLowerCase()); // *hello*
}
}
范例:去掉空格
public class Demo {
public static void main(String[] args) {
String str = " Hello World ";
System.out.println("【" + str + "】"); // 【 Hello World 】
System.out.println("【" + str.trim() + "】"); // 【Hello World】
}
}
用户进行数据输入时,可能携带无用的空格,接收到这些数据后就要消掉这些无用的空格,这时候就用到了trim()
。
范例:取得字符串长度
public class Demo {
public static void main(String[] args) {
String str = "Hello World";
System.out.println(str.length()); // 11
}
}
某些情况要求用户输入的数据长度有限制,可以利用此方法判断。
范例:判断是否是空字符串
public class Demo {
public static void main(String[] args) {
String str = "";
System.out.println(str.isEmpty()); // true
System.out.println("".equals(str)); // true
}
}
范例:实现首字母大写,其余字母小写
public class Demo {
public static void main(String[] args) {
String str = "hElLo";
System.out.println(initcap(str)); // Hello
}
public static String initcap(String temp) {
// 截取第一个字母,将其变为大写;截取首字母之后的字母将其变为小写
return temp.substring(0, 1).toUpperCase() + temp.substring(1).toLowerCase();
}
}