1 字符串String类
1.1 String概述
字符串是一个对象,不是基础数据类型(八大基础数据类型:byte、int、short、long;float、double、char、boolean)。
字符串一旦被初始化,就不可以被改变,存放于方法区的常量池中。
String类重写了Object类的equals()方法,用来判断字符串的内容是否相同。
字符串String类代码实例:
class StringDemo{
public static void main(String[] args){
String s1 = "abc"; //s1是一个类类型变量,"abc"是一个对象
//字符串最大特点:一旦被初始化,就不可以被改变。
s1 = "kk";
System.out.println(s1); //打印结果是"kk",并不是字符串对象变了,而是s1指向的引用变了
//s1引用指向了新的"kk"字符串对象,而"abc"没有再被引用。
String s2 = new String("kk"); //此定义格式等同于s1的定义格式,但也有区别。
/* s1和s2两种定义方式什么区别?
s1代表一个对象,
s2有两个对象。new是一个对象,"kk"又是一个对象 */
System.out.println(s1==s2); //false,不是同一个对象的引用
System.out.println(s1.equals(s2)); //true,String类重写了Object类中的equals方法,该方法判断字符串内容是否相同。
}
}
1.2 String类常用方法:获取、判断
String类是用于描述字符串的类,那么它就提供了多个方法对字符串进行操作。
常见的方法有哪些:
1、获取。
1.1 字符串中包含的字符数,也就是字符串的长度。
int length():获取字符串长度。
1.2 根据位置获取位置上的某个字符。
char charAt(int index):返回当前字符串第index位置上的字符。
1.3 根据字符获取该字符在字符串中的位置。
int indexOf(int ch):返回的是ch在字符串中第一次出现的位置,参数中的int类型是传递字符的ASCII值。
int indexOf(int ch, int fromIndex):从fromIndex指定位置开始,获取ch在字符串中出现的位置。
int indexOf(String str):返回的是str在字符串中第一次出现的位置,str为子串。
int indexOf(String str, int fromIndex):从fromIndex指定位置开始,获取子串str在字符串中出现的位置。
int lastIndexOf(int ch):返回字符ch在当前字符串中最后一次出现时的位置。
若没找到,返回-1.
2、判断。
2.1 字符串中是否包含某一个子串。
boolean contains(String str);
特殊之处:indexOf(String str):可以查找str第一次出现的位置,如果返回-1,表示该str不在字符串中存在。所以,也可以用于判断字符串中是否包含某一个子串。
if(str.indexOf("aa")!= -1)
而且该方法既可以判断,又可以获取出现的位置。
2.2 字符串中是否有内容。
boolean isEmpty():原理就是判断长度是否为0.
2.3 字符串是否是以指定内容开头。
boolean startsWith(String str);
2.4 字符串是否是以指定内容结尾。
boolean endsWith(String str);
2.5 判断字符串内容是否相同。重写了Object类中的equals方法。
boolean equals(String str);
2.6 判断字符串内容是否相同,并忽略大小写。
boolean equalsIgnoreCase();
获取和判断的代码示例:
class StringMethodDemo{
public static void method_get(){
String str = "abcdeabpf";
sop(str.length()); //返回字符串str的长度
sop(str.charAt(3)); //返回字符串str中脚标为3的字符,即d
sop(str.indexOf('d'));//返回字符串str中,字符'd'的脚标。
sop(str.indexOf('a',4)); //从脚标为4开始查找,返回字符'a'的脚标。
sop(str.indexOf("bcd")); //返回字符串str中,子字符串bcd的位置
sop(str.indexOf("ab",4));//从脚标为4开始查找,返回子字符串"ab"在str中开始的脚标。
sop(str.lastIndexOf('a'));//返回字符'a'在字符串str中最后一次出现的脚标。
}
public static void method_is(){
String str = "ArrayDemo.java";
sop(str.contains("Demo"));//判断字符串str中是否包含子串"Demo"
sop(str.isEmpty());//判断字符串str是否为空
sop(str.startsWith("Array"));//判断字符串str是否以"Array"开头
sop(str.endsWith(".java"));//判断字符串str是否以".java"结尾
}
public static void sop(Object obj){
System.out.println(obj);
}
public static void main(String[] args){
method_get();
sop(" ");
method_is();
}
}
1.3 String类常用方法:转换
3、转换。
3.1 将字符数组转成字符串。
构造函数:String(char[] value);
将字符数组value转换成字符串并初始化。
String(char[] value, int offset, int count);
将字符数组中,从脚标offset开始,长度为count的count个字符,转换成字符串。
静态方法:Static String copyValueOf(char[] data);
static String copyValueOf(char[] data, int offset, int count);
static String valueOf(char[] data);
static String valueOf(char[] data, int offset, int count);
3.2 将字符串转成字符数组。**
char[] toCharArray();
3.3 将字节数组转成字符串。
构造函数:String(byte[] b);
String(byte[] b, int offset, int count);
3.4 将字符串转成字节数组。
byte[] getBytes();
3.5 将基本数据类型转成字符串。
static String valueOf(int i);
static String valueOf(double d);
例如 3+""; //String.valueOf(3);
特殊:字符串和字节数组在转换过程中,是可以指定编码表的。
转换方法的代码示例:
class StringMethodDemo2{
public static void method_trans(){
char[] arr = {'a','b','c'};
String str1 = new String(arr); //把字符数组arr[]转换成字符串。
String str2 = new String(arr,1,2); //把字符串arr[]中从脚标为1开始的2个字符,转换成字符串。
sop(str1);
sop(str2);
String str = "opqrst";
char[] arr2 = str.toCharArray(); //把字符串str转换成字符数组arr2
byte[] arr3 = str.getBytes(); //把字符串str转换成字节数组arr3
for(char element : arr2) //增强for循环遍历数组
System.out.print(element+" ");
System.out.println(); //只为换行
for(byte element : arr3)
System.out.print(element+" ");
}
public static void sop(Object obj){
System.out.println(obj);
}
public static void main(String[] args){
method_trans();
}
}
1.4 String类常用方法:替换、切割和获取子串
4、替换。
String replace(char oldChar, char newChar);
用新的字符来替换当前字符串中旧的字符,返回新的字符串。
String replace(CharSequence target, CharSequence replacement);
CharSequence为字符串接口,String类是其子类。
则CharSequence当然可接收String对象,即:
新的子字符串,替换旧的子串。
5、切割。
String[] split(String regex);
把当前字符串,以字符串regex为依据,进行切割。返回切割后的字符串数组。
6、子串。获取字符串中的一部分。
String substring(int beginIndex);
返回当前字符串中,从脚标 beginIndex 开始到结尾的子字符串。
String substring(int beginIndex, int endIndex)
返回当前字符串中,从脚标 beginIndex 到 endIndex-1 的子字符串。
beginIndex - 起始索引(包括)。
endIndex - 结束索引(不包括)。
替换、切割和获取子串的代码示例:
public class StringMethodDemo3{
public static void method_replace(){
String str = "hello java"; //str已经初始化,不能被改变,只能生成新的字符串
String str1 = str.replace('a','b'); //用'b'替换str中的'a',新字符串对象的地址赋值给str1
String str2 = str.replace('p','b'); //如果要替换的字符不存在,返回的还是原串
sop(str1);
sop(str2);
String str3 = str.replace("java","world"); //用新的子字符串,替换旧的子串
sop(str3);
}
public static void method_split(){
String str = "zhangsanmmlisimmwangwu";
String[] arr = str.split("mm"); //把str字符串,以字符串"mm"为依据,进行切割,返回字符串数组
for(int x=0; x<arr.length; x++)
sop(arr[x]);
}
public static void method_sub(){
String str = "abcdef";
String str1 = str.substring(2); //返回字符串str中,从脚标2开始到结尾的子字符串
String str2 = str.substring(2,4); //返回字符串str中,从脚标2到脚标3的子字符串
sop(str1);
sop(str2);
}
public static void sop(Object obj){
System.out.println(obj);
}
public static void main(String[] args){
method_replace();
method_split();
method_sub();
}
}
1.5 String类常用方法:转换大小写、去除空格、比较
7 将字符串转成大写或者小写。
String toUpperCase(); //将当前字符串转成全部大写。
String toLowerCase(); //将当前字符串转成全部小写。
8 将字符串两端的多个空格去除。
String trim(); //去除字符串两端的多个空格。
9 对两个字符串进行自然顺序的比较。
int compareTo(String str);
按字典顺序,比较两个字符串中各个字符的Unicode值;
若当前String对象位于参数字符串之前,返回一个负数(第一个不同字符的ascii码相减);
若当前String对象位于参数字符串之后,返回一个正数;
若两个字符串的顺序相等,返回0.
如果此字符串按字典顺序小于字符串参数,则返回一个小于 0 的值;
如果此字符串按字典顺序大于字符串参数,则返回一个大于 0 的值。
如果参数字符串等于此字符串,则返回值 0;
转换大小写、去除两端、比较字符串顺序的代码示例:
public class StringMethodDemo4{
public static void method_toUpperCase(){
String str = "Hello Java";
String str1 = str.toUpperCase(); //转成全部大写
sop(str1);
}
public static void method_toLowerCase(){
String str = "Hello Java";
String str1 = str.toLowerCase(); //转成全部小写
sop(str1);
}
public static void method_trim(){
String str = " Hello Java ";
String str1 = str.trim(); //去除两端所有空格
sop(str1);
}
public static void method_compareTo(){
String str1 = "a1c"; //1 的ascii码是49
String str2 = "aaa"; //a 的ascii码是97
int s = str1.compareTo(str2); //1 的ascii值减 a的ascii值,第二个数不同则第二个之后的不再比较。返回-48
sop(s);
}
public static void sop(Object obj){
System.out.println(obj);
}
public static void main(String[] args){
method_toUpperCase();
method_toLowerCase();
method_trim();
method_compareTo();
}
}
2. 字符串缓冲区StringBuffer和StringBuilder
StringBuffer和StringBuilder是字符串缓冲区,是存放字符串的容器,都有相同的功能。
不同的是,StringBuffer考虑到了多线程的安全问题,而StringBuilder没有,即StringBuffer是线程安全的,而StringBuilder是线程不安全的。
因为StringBuffer考虑线程同步,需要判断锁,运行较慢。所以StringBuilder效率较高,但只能在单线程时使用。
单线程使用StringBuilder,多线程使用StringBuffer。
它们的常用功能有:存储、删除、获取、修改、反转、getChars()。
特点:
1,它们的长度是可变化的,而数组的长度是不可变化的。
2,可以直接操作多个数据类型。
3,最终会通过toString()方法变成字符串。
常见的四大操作——CURD:Create、Update、Read、Delete。
1,存储:
append(数据):将指定数据(任意类型)作为参数添加到已有数据的结尾处。
insert(index,数据):可以将数据(任意类型)插入到指定index的位置。
2,删除:
delete(start,end):删除缓冲区中的数据,包含start不包含end。
deleteCharAt(index):删除指定位置的字符。
3,获取:
charAt(int index):通过脚标获取字符。
indexOf(String str):获取子串str在当前字符串中的位置。
substring(int start):获取子串,从start到结尾。
substring(int start,int end):获取子串,从start到end,包含start不包含end。
4,修改:
replace(int start, int end, String str):把从start到end的部分替换为str,包含start不包含end,返回的依然是StringBuffer。
setCharAt(int index, char ch):把index位置的字符替换为ch。
5,反转:
reverse():把缓冲池中的字符串反转,返回依然是StringBuffer。
6,将缓冲区中指定数据存储到指定字符数组中:
getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin):把缓冲区中字符串从srcBegin到srcEnd(包含头不包含尾)存到字符数组dst[]中,从数组的dstBegin脚标位开始存。
StringBuffer和StringBuilder常用方法示例:
class StringBufferDemo{
public static void main(String[] args){
method_getChars();
}
public static void sop(Object obj){
System.out.println(obj);
}
//StringBuffer的存储:append、insert。
public static void method_add(){
StringBuffer sb = new StringBuffer(); //append从字符串缓冲池尾部开始添加字符。
sb.append("abc").append(true).append(34); //把"abc"、true和34转换成字符串,依次加入字符串缓冲池。
sop("缓冲区中的字符串:"+sb);
sb.insert(1,22); //在字符串脚标为1的位置插入22.
sop("insert操作后:"+sb);
}
//StringBuffer的删除:delete。
public static void method_del(){
StringBuffer sb = new StringBuffer();
sb.append("abc").append(true).append(34);
sop("缓冲区中的字符串:"+sb);
sb.delete(3,7); //删除脚标从3到7的字符,包含3不包含7。
sop("delete操作后:"+sb);
sb.delete(0,sb.length()); //清空缓冲区,容器StringBuffer消失了。
sop(sb.length());
}
//StringBuffer的获取:charAt()、indexOf()、substring()。
public static void method_get(){
StringBuffer sb = new StringBuffer();
sb.append("abc").append(true).append(34);
sop("缓冲区中的字符串:"+sb);
char arr = sb.charAt(2); //获取脚标为2的字符。
int index = sb.indexOf("34"); //获取字符串"34"的位置
String str = sb.substring(3); //获取从脚标3到末尾的子串
sop("脚标为2的字符:........"+arr);
sop("34的位置:............."+index);
sop("子串:................."+str);
}
//StringBuffer的修改:replace(start,end,str)、setCharAt(index,char)。
public static void method_mo(){
StringBuffer sb = new StringBuffer();
sb.append("abc").append(true).append(34);
sop("缓冲区中的字符串:"+sb);
sb.replace(3,7,"false"); //把从3到6的子串替换为"false"
sb.setCharAt(sb.length()-1,'9'); //把最后一个字符替换为'9'
sop("修改后:..............."+sb);
}
//StringBuffer的反转:reverse()。
public static void method_re(){
StringBuffer sb = new StringBuffer();
sb.append("abc").append(true).append(34);
sop("缓冲区中的字符串:"+sb);
sb.reverse();
sop("反转后:..............."+sb);
}
//6,getChars(start,end,char[],index):
public static void method_getChars(){
StringBuilder sb = new StringBuilder();
sb.append("abc").append(true).append(34);
sop("缓冲区中的字符串:"+sb);
char[] arr = new char[6];
sb.getChars(3,7,arr,1); //把从3到6的字符串"true"存到字符数组arr[]中,从数组的脚标1开始存。
for(int x=0; x<arr.length; x++){
sop("arr["+x+"]="+arr[x]+";");
}
}
}
3 String类常用方法的练习
练习1,模拟一个trim()方法,去除字符串两端的空格。
思路:
1,判断字符串第一个位置是否是空格,如果是则继续向下判断,直到不是空格为止。结尾处判断空格也是如此。
2,当开始和结尾都判断到不是空格时,就是要获取的字符串。
练习2,将一个字符串进行反转。将字符串中指定部分进行反转,“abcdefg”;abfedcg
思路:
1,曾经学习过对数组元素进行反转。
2,将字符串变成数组,对数组反转。
3,将反转后的数组变成字符串。
4,只要将反转部分的开始和结束为止作为参数传递即可。
练习3,获取一个字符串在另一个字符串中出现的次数,“abkkcdkkefkkgkk”
思路:
1,定义一个计数器。
2,获取kk第一次出现的位置。
3,从第一次出现位置后剩余的字符串中继续获取kk出现的位置。每获取一次就计数一次。
4,当获取不到时,计数完成。
练习4,获取两个字符串中最大相同子串。第一个动作:将短的那个串进行长度依次递减的子串打印。“abcwerthelloyuiodef”,“cvhellobnm”
思路:
1,将短的那个字符串的子串按照长度递减的方式获取到。
2,将每获取到的子串去长的字符串中判断是否包含。如果包含,已经找到!
以上练习的代码和注释:
public class StringTest{
public static void main(String[] args){
String s1 = "abcwerthelloyuiodef";
String s2 = "cvhellobnm";
sop(getMaxSubString(s1,s2));
}
public static void sop(Object obj){
System.out.println(obj);
}
//练习1,自己写一个String的trim()方法
public static String myTrim(String str){
int start = 0, end = str.length()-1; //字符串的length()带()
while(start<=end && str.charAt(start)==' ')
start++;
while(start<=end && str.charAt(end)==' ')
end--;
String str1 = str.substring(start,end+1);
return str1;
}
//练习2,将字符串反转
public static String reverseString(String str,int start,int end){ //部分反转
String str1 = str.substring(start,end+1);
String str2 = reverseString(str1);
char[] arr = str.toCharArray();
char[] arr1 = str2.toCharArray();
for(int x=start,i=0; x<=end && i<arr1.length; x++,i++){
arr[x] = arr1[i];
}
return new String(arr);
}
public static String reverseString(String str){ //全部反转
char[] arr = str.toCharArray();
reverse(arr);
return new String(arr);
}
private static void reverse(char[] arr){ //数组顺序反转
for(int start=0,end=arr.length-1; start<end; start++,end--){ //数组的length不带括号
char temp = arr[start];
arr[start] = arr[end];
arr[end] = temp;
}
}
//练习3,获取一个字符串在另一个字符串中出现的次数
public static int getSubCount(String str,String key){ //获取key在str中出现的次数
int count = 0;
int index = 0;
while((index=str.indexOf(key))!=-1){
sop("str:"+str);
str = str.substring(index+key.length());
count++;
}
return count;
}
//练习3,方式二:使用 indexOf(String str, int fromIndex):从fromIndex指定位置开始,获取str在字符串中出现的位置
public static int getSubCount2(String str,String key){
int count = 0;
int index = 0;
while((index=str.indexOf(key,index))!=-1){
sop("index:"+index);
index = index + key.length();
count++;
}
return count;
}
//练习4,以长度递减的顺序获取较短字符串的所有子串,每获取一个再依次判断较长字符串是否也包含此子串。
public static String getMaxSubString(String s1,String s2){
String max="",min="";
max = (s1.length()>s2.length())?s1:s2;
min = (max==s1)?s2:s1;
sop("max="+max+"...min="+min);
String temp = "";
xunhuan:
for(int x=0; x<min.length(); x++){
for(int y=0,z=min.length()-x; z<=min.length(); y++,z++){
temp = min.substring(y,z); //返回从脚标 y 到(z-1)的子串。
//sop(temp);
if(max.contains(temp)) //if(max.indexOf(temp)!=-1)
break xunhuan;
}
}
return temp;
}
}