String类的概述
字符串是由多个字符组成的一串数据(字符序列),字符串可以看成是字符数组。在实际开发中,字符串的操作是最常见的操作,没有之一,而Java没有内置的字符串类型,所以,就在Java类库中提供了一个String类供我们来使用。
String类的特点
- 字符串是常量,它的值在创建之后不能更改;
- Java程序中的所有字符串字面值(如"abc")都作为此类的实例实现;
- 字符串如果是变量相加,先开空间,再拼接;
- 字符串如果是常量相加,是先加,然后在常量池找,如果有就直接返回,否则,就创建。
请观察如下程序代码,试着思考字符串是如何在内存中体现的。
package cn.liayun.test;
public class StringDemo {
public static void main(String[] args) {
String str = "hello";
str += "world";
System.out.println("str: " + str);//str: helloworld
}
}
字符串在内存中的体现如下图:
再来看以下程序代码,问str和str1的区别?
package cn.liayun.test;
public class StringDemo {
public static void main(String[] args) {
//问,str和str1的区别?
String str = "abcd";
String str1 = new String("abcd");
System.out.println(str == str1);//false
System.out.println(str.equals(str1));//true,字符串的equals()方法覆盖了Object类,比较的是字符串的内容是否相同。
}
}
答案:str在内存中只有一个对象,str1在内存中有两个对象。
字符串在内存中的体现如下图:
String类的常见操作方法
String类是用于描述字符串事物的,那么它就提供了多个方法对字符串进行操作,常见的操作有哪些呢?
获取功能
- 获取字符串长度,字符串中包含的字符数,也就是字符串的长度。
- 根据位置获取位置上某个字符。
- 根据字符获取该字符在字符串中的位置,并且返回的是ch在字符串中第一次出现的位置。
- 从fromIndex指定位置开始,获取ch在字符串中出现的位置。
- 获取str在字符串中第一次出现的位置。
- 从fromIndex指定位置开始,获取str在字符串中出现的位置。
- 反向索引一个字符出现的位置。
- 获取字符串中的一部分。
- 从指定位置开始截取字符串。
- 截取字符串,包左不包右。
- 从指定位置开始截取字符串。
package cn.liayun.test;
public class StringDemo {
public static void main(String[] args) {
method_get();
}
private static void method_get() {
String str = "abcdeakpf";
//获取字符串的长度。
System.out.println(str.length());
//根据索引获取字符。
System.out.println(str.charAt(4));//当访问到字符串中不存在的角标时,会发生StringIndexOutOfBoundsException。
//根据字符获取索引。
System.out.println(str.indexOf('m', 3));//如果没有找到返回-1。
//反向索引一个字符出现的位置。
System.out.println(str.lastIndexOf('a'));
}
}
判断功能
-
字符串中是否包含某一个子串。
特殊之处:
该方法可以索引str第一次出现的位置,如果返回-1,表示该str不在字符串中存在,所以,也可以用于对指定字符串判断是否包含,而且该方法既可以判断,又可以获取出现的位置。 -
字符串是否有内容,原理就是判断长度是否为0。
-
字符串是否是以指定内容开头。
-
字符串是否是以指定内容结尾。
-
判断字符串的内容是否相同,复写了Object类中的equals()。
-
判断内容是否相同,并忽略大小写。
package cn.liayun.test;
public class StringDemo {
public static void main(String[] args) {
method_is();
}
private static void method_is() {
String str = "ArrayDemo.java";
// 判断文件名称是否是以Array单词开头
System.out.println(str.startsWith("Array"));
// 判断文件名称是否是.java文件
System.out.println(str.endsWith(".java"));
// 判断文件名称是否包含Demo
System.out.println(str.contains("Demo"));
}
}
转换功能
- 将字符数组转成字符串。
- 构造函数。
将字符数组中的一部分转成字符串 ,count是个数。 - 静态方法。
- 构造函数。
- 将字符串转成字符数组。
- 将字节数组转成字符串。
- 构造函数。
将字节数组中的一部分转成字符串。
- 构造函数。
- 将字符串转成字节数组。
- 将基本数据类型转成字符串。
将基本数据类型转成字符串还有一个更简单的方法,那就是:3+""; // String.valueOf(3); int—>String
package cn.liayun.test;
public class StringDemo {
public static void main(String[] args) {
method_trans();
}
private static void method_trans() {
char[] arr = {'a','b','c','d','e','f'};
String s = new String(arr, 1, 3);
System.out.println("s = " + s);
String s1 = "zxcvbnm";
char[] chs = s1.toCharArray();
for (int i = 0; i < chs.length; i++) {
System.out.println("chs[" + i + "] = " + chs[i]);
}
}
}
注意:字符串和字节数组在转换过程中,是可以指定编码表的。
替换功能
- 替换字符。
- 替换字符串。
package cn.liayun.test;
public class StringDemo {
public static void main(String[] args) {
method_replace();
}
private static void method_replace() {
String s = "hello java";
// String s1 = s.replace('q', 'n');//如果要替换的字符不存在,返回的还是原串
String s1 = s.replace("java", "world");
System.out.println("s = " + s);
System.out.println("s1 = " + s1);
}
}
切割功能
方法:
package cn.liayun.test;
public class StringDemo {
public static void main(String[] args) {
method_split();
}
private static void method_split() {
String s = "zhangsan,lisi,wangwu";
String[] arr = s.split(",");
for (int x = 0; x < arr.length; x++) {
System.out.println(arr[x]);
}
}
}
其他功能
- 将字符串转成大写。
- 将字符串转成小写。
- 去除字符串两端的空白。
- 对两个字符串进行自然顺序的比较。
package cn.liayun.test;
public class StringDemo {
public static void main(String[] args) {
method_else();
}
private static void method_else() {
String s = " Hello Java ";
System.out.println(s.toUpperCase());
System.out.println(s.toLowerCase());
System.out.println(s.trim());
String s1 = "a1c";
String s2 = "aaa";
System.out.println(s1.compareTo(s2));
}
}
有关String类的练习题
字符串可以比较大小吗?
字符串可以比较大小吗?如果有!将字符串数组排序。
分析:基本类型数值可以通过比较运算符(>、==、<)比较大小和相等。对象亦可以比较是否相等,谁大谁小,都是通过方法完成的。对象比较相同用的是Object类的equals()方法,子类一般情况下都会复写,建立自己判断相同的依据。对象比大小,用的也是方法,该功能有3种情况,所以使用int类型——正数、负数、0。前者大于后者返回正数,前者小于后者返回负数,前者等于后者返回零。
public class StringTest {
public static void main(String[] args) {
String[] strs = {"haha", "nba", "abc", "cba", "haha", "qq", "hiahia"};
printArray(strs);
// 对字符串数组排序
sort(strs);
printArray(strs);
}
public static void sort(String[] strs) {
for (int x = 0; x < strs.length - 1; x++) {
for (int y = x + 1; y < strs.length; y++) {
if (strs[x].compareTo(strs[y]) > 0) {
swap(strs, x, y);
}
}
}
}
private static void swap(String[] strs, int x, int y) {
String temp = strs[x];
strs[x] = strs[y];
strs[y] = temp;
}
public static void printArray(String[] strs) {
for (int i = 0; i < strs.length; i++) {
if (i != strs.length - 1) {
System.out.print(strs[i] + ",");
} else {
System.out.println(strs[i]);
}
}
}
}
子串在整串中出现的次数
获取一个字符串在另一个字符串中出现的次数。例如,”kk”在”abkkcdkkefkkskk”出现的次数。
思路:
- 定义一个计数器;
- 获取”kk”第一次出现的位置;
- 从第一次出现的位置后剩余的字符串中继续获取”kk”出现的位置,每获取一次就计数一次;
- 当获取不到时,计数完成。
public class StringTest {
public static void main(String[] args) {
String str = "nbadfnbaghjnbaklnba";
String key = "nba";
int count = getKeyCount(str, key);
System.out.println("count = " + count);
}
public static int getKeyCount(String str, String key) {
// 1,定义变量计数
int count = 0;
// 2,定义变量,记录每次找到的角标
int index = 0;
// 2,循环。条件是indexOf查找方法返回的结果不是-1,而且要明确下次查找的位置,indexOf(String, fromIndex);
while ((index = str.indexOf(key, index)) != -1) {
count++;
// 每找完一次,都要确定下次要找的起始位置。上次位置+key的长度
index += key.length();
}
return count;
}
}
两个字符串中的最大相同子串
获取两个字符串中的最大相同子串。例如,”abcwerthelloyuiodef”和”cvhellobnm”。
思路:
- 以短的字符串为主,到长的字符串中去判断是否存在,如果存在,已找到;
- 如果没有找到,将短的字符串的长度递减,获取子串,继续到长的串中查找,只要找到就结束;
- 没有找到,说明没有相同的。
public class StringTest {
public static void main(String[] args) {
String s1 = "sadfcctvghjkl";
String s2 = "zxcctvcv";
String maxSub = getMaxSubString(s1, s2);
System.out.println("maxSub = " + maxSub);
}
public static String getMaxSubString(String s1, String s2) {
// 确定哪个是长的哪个是短的
String longStr, shortStr;
longStr = s1.length() > s2.length() ? s1 : s2;
shortStr = s1.equals(longStr) ? s2 : s1;
// System.out.println("long:" + longStr);
// System.out.println("short:" + shortStr);
// 对短的字符串操作,从短串中取子串,到长字符串中判断,是否存在
for (int x = 0; x < shortStr.length(); x++) {
for (int y = 0, z = shortStr.length() - x; z <= shortStr.length(); y++, z++) {
// 根据y、z获取子串
String temp = shortStr.substring(y, z);
// System.out.println(temp);
if (longStr.contains(temp)) {
return temp;
}
}
}
return null;
}
}
对字符串中字符进行自然顺序排序
对字符串中的字符进行自然顺序排序。
思路:
- 要排序,我会!但是只会数组排序。
- 怎么能把字符串转成数组呢?
- 到字符串中找方法
- 排序我熟
- 将排序后的数组变成字符串
public class StringTest {
public static void main(String[] args) {
String str = "jbdsakncv";
String sortString = sortChar(str);
System.out.println(sortString);
}
/**
* 对给定的字符串中的字符进行自然排序,并返回排序后的字符串
* @param str
* @return
*/
public static String sortChar(String str) {
// 1,将字符串转成字符数组
char[] chs = stringToArray(str);
// 2,对数组排序
sort(chs);
// 3,将数组转成字符串
return toString(chs);
}
/*
* 将字符数组转成字符串
*/
private static String toString(char[] chs) {
return new String(chs);
}
/*
* 对字符数组进行升序排序
*/
private static void sort(char[] chs) {
Arrays.sort(chs);
}
/*
* 将字符串转成字符数组
*/
private static char[] stringToArray(String str) {
return str.toCharArray();
}
}