------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
一、String类概述
java中用String类进行描述对字符串进行了对象的封装。这样的好处是可以对字符串这种常见数据进行方便的操作。对象封装后,可以定义N多属性和行为。
String类是final的,也就是说它没有子类。
二、String字符串的特点
1、字符串一旦被初始化就不可以被改变。并且存放在方法区中的常量池中。
1 class StringDemo{2 public static void main(String[] args){3 String s = "黑马";4 s = "安卓";5 System.out.println("s = " + s);//安卓;其实"黑马"字符串对象并没有被改变,只是引用变量s指向了新字符串对象"安卓"。6 }7 }
2、String s="abc"//s是一个类类型的变量,"abc"是一个对象。
3、 String s = new String();//等效于String s = "";不等效于String s = null;
4、字符串的比较
1 String s1="abc"//指向的内存中只有一个对象abc2 String s2=new String("abc");//s2指向的内存中有两个对象:abc、new出来的3 String s3="abc";4 5 System.out.println(s1==s2);//false,"=="代表的是两个对象的内存地址值是否一样,显然两个对象两个地址值。6 7 System.out.println(s1==s3);//true;因为String存放在常量池中,因为“abc”这个字符串对象已经在内存中存在,为了节约内存,在字符串对象当中只要字符串相同,那么s1和s3就指向同一个对象。8 9 System.out.println(s1.equals(s2));//true;在Object类中equals是比较的两个对象的内存地址值,和“==”一样,但是在String类中String复写了Object中的equals的方法,建立自己独特的方法:就是比较两个字符串的内容是否相同
5、s1和s2有什么区别呢?
s1在内存中只有一个对象,而s2在内存中有两个对象。
三、String类中常用方法
1、构造方法
1 new String();//创建一个空的字符串对象 2 new String(byte[] bytes);//通过使用平台的默认字符编码指定的 byte 数组创建字符串对象 3 new String(byte[] bytes,Charset charset);//通过使用指定编码指定的byte数组创建字符串对象 4 new String(byte[] bytes,int offset, int length); 5 new String(byte[] bytes,int offset, int length,Charset charset); 6 new String(byte[] bytes, String charsetName) ;// 通过使用指定的 charset 解码指定的 byte 数组,创建字符串对象 7 new String(char[] value) 8 new String(char[] value, int offset, int count) 9 new String(String s) 10 new String(StringBuffer buffer) 11 new String(StringBuilder builder)
代码演示:
1 class StringDemo 2 { 3 public static void main(String[] args)throws Exception 4 { 5 method_1(); 6 method_2(); 7 } 8 public static void method_1()throws Exception{ 9 byte[] by={'h','e','l','l','o'};10 String s=new String(by);11 System.out.println("s="+s);12 s=new String(by,2,3);//起始位是2角标,往后打印3个长度13 System.out.println("s="+s);//s=llo14 s=new String("您好".getBytes(),"GBK");15 System.out.println("s="+s);//s=您好16 }17 public static void method_2(){18 char[] ch={'我','是','黑','马'};19 String s=new String(ch);20 System.out.println(s);//我是黑马21 System.out.println(new String(ch,2,2));//黑马22 }23 }
2、成员方法
(1)、获取
1 int length();//获取字符串的长度 2 char charAt(int index);//根据位置获取位置上某个字符 3 4 //indexOf方法参数类型为int是为了既可以支持字符,也可以支持字符在ASCII码中对应的数字。 5 6 int indexOf(int ch);//返回第一次找到的字符角标。如果不存在返回-1,所以可以通过返回值-1来判断某一个字符不存在的情况。 7 int indexOf(int ch,int fromIndex);//从fromIndex指定位置开始,获取ch在字符串中出现的位置。 8 int indexOf(String str);//返回的是字符串str在整个字符串中第一次出现的位置。 9 int indexOf(String str,int fromIndex);//:从fromIndex指定位置开始,获取str在字符串中出现的位置。10 int lastIndexOf(int ch);//返回指定字符在此字符串中最后一次出现处的索引11 int lastIndexOf(int ch,int fromIndex);12 int lastIndexOf(String str);13 int lastIndexOf(String str,int fromIndex);
(2)、判断
1 boolean contains(Sting str);//判断字符串中师傅包含某一个字串2 //特殊之处:indexOf(String str):可以索引str第一次出现的位置,如果返回-1,表示该str不再字符串中存在。所以,也可以用contains方法对指定字串判断是否包含。但是:indexOf("aa")既可以判断也可以获取出现的位置3 4 boolean isEmpty();//字符串中是否有内容,其实原理就是判断长度是否为05 boolean startsWith(String str);//判断字符串是否是以指定的内容开头6 boolean endsWith(String str);//判断字符串是否是以指定的内容结尾7 boolean equals(String str);//判断字符串中内容是否相同,复写了Object类中的equals方法8 boolean equalsIgnoreCase(String str);//判断内容是否相同,并忽略了大小写 9 boolean matches(String regex);//判断此字符串是否匹配指定的正则表达式
(3)、转换
1、将字符数组转换成字符串
构造方法:
1 new String(char[] chs)2 new String(char[] chs,int offfset,int count)//cout 是个数
静态方法:
1 String.copyValueOf(char[] data);2 String.copyValueOf(char[] data,int offset,int count);3 4 String.valueOf(char[] data);5 String.valueOf(char[] data,int offset,int count);
2、将字符串转成字符数组
1 char[] toCharArray();
3、将字节数组转成字符串
字节数组转成字符串只有构造函数可以用,并没有静态方法。这与字符数组转字符串不同
1 new String(byte[] bytes);2 new String(byte[] bytes,int offset,int count);//将字节数组中的一部分转成字符串
4、将字符串转换成字节数组
1 byte[] getBytes()
5、将基本数据类型转换成字符串
1 String.valueOf(int c);2 String.valueOf(double d);3 String.valueOf(char c);4 String.valueOf(float f);5 Stirng.valueOf(long l);6 String.valueOf(Object obj);//返回 Object 参数的字符串表示形式 7.String.valueOf(boolean b);
3+””和String,valueOf(3)是一样的
特殊:字符串和字节数组在转换过程中,是可以制定编码表的
(4)、替换
1 String replace(oldChar,newChar);2 String replace(String s1,String s2);3 //如果replace方法没有找到要替换的内容,则返回的还是原字符串 4 //注意:修改后变成新字符串,并不是将原字符串直接修改。
(5)、切割
1 String[] split(regex);//正则表达式切割。返回的是字符串数组
(6)、获取字串。获取字符串中的一部分
1 String substring(int begin);//从指定位置开始到结尾,如果角标不存在,会出现字符串角标越界异常2 String substring(int begin,int end);//包含头,不包含尾
(7)、转换、去除空格、比较、连接、设置字符长度
1、将字符串转成大写或者小写
1 String toUpperCase();//转换成大写2 String toLowerCase();//转成小写
2、将字符串两端的多余空格去除
1 String trim();
3、对两个字符串进行自然顺序的比较
1 int compareTo(String str);2 //如果参数字符串等于此字符串,则返回值0;如果此字符串按自然顺序小于字符串参数,则返回一个小于0的值;如果此字符串按自然顺序大于字符串参数,则返回一个大于0的值。
4、将字符串进行连接
1 String concat(String str);//concat效果与“+”连接符效果一致,但是效果更高一些
5、设置字符序列长度
1 void setLength(int newLength);//使用setLength设置StringBuffer中字符序列的长度。如果小于已有字符序列的长度,相当于清除缓冲区中的一部分内容。如果大于已有字符序列的长度,相当于扩充缓冲区,扩充部门内容用空格字符填充。2 //当创建的StringBuffer内容长度大于16,将会新创建一个新数组,长度比旧数组要长。然后把就数组的内容拷贝到新的数组,超出旧数组长度范围的内容将会放在新数组现在内容的后面,也可以通过StringBuffer(int capacity);构造函数自己设置StringBuffer缓冲区长度
代码演示:
1 import java.util.*; 2 class StringDemo 3 { 4 public static void sop(Object obj){ 5 System.out.println(obj); 6 } 7 public static void main(String[] args){ 8 String str="我是黑马,我在黑马,我是黑马程序员"; 9 get(str); 10 is(str); 11 transform(str); 12 split(str); 13 replace(str); 14 substring(str); 15 stringcase(); 16 trim(); 17 compareTo(); 18 } 19 //获取 20 public static void get(String str){ 21 sop("length="+str.length()); 22 for (int x=0;xcomp=Collections.reverseOrder(new LenComparator());//强行逆转实现Comparator接口原有的比较顺序120 Arrays.sort(arr,comp);121 sop(Arrays.toString(arr));//[haha, nba, abc, cba, zz, qq]122 }123 }124 class LenComparator implements Comparator 125 {126 public int compare(String s1,String s2){127 return s1.length()-s2.length(); 128 }129 }
需求:模拟一个trim方法,去除字符串两端的空格。
1 //模拟一个trim方法,去除字符串两端的空格。 2 /* 3 思路: 4 1.定义两个变量。 5 一个变量作为从头开始判断字符串空格的角标,不断++。 6 一个变量作为从尾开始判断字符串空格的角标,不断--。 7 2.判断到不是空格为止,取头部之间的字符串即可。 8 */ 9 class StringTest10 {11 public static void main(String[] args) 12 {13 String str=" abc de ";14 sop("去除空格前:"+str);15 str=myTrim(str);16 sop("去除空格后:"+str);17 }18 public static String myTrim(String str){19 int start=0;20 int end=str.length()-1;21 while(start<=end && str.charAt(start)==' ')22 start++;23 while(start<=end && str.charAt(end)==' ')24 end--; 25 return str.substring(start,end+1);26 }27 public static void sop(Object obj){28 System.out.println(obj);29 }30 }
需求:将一个字符串进行反转。
1 class StringTest 2 { 3 public static void main(String[] args) 4 { 5 String str="abc de f "; 6 System.out.println(reverse(str)); 7 } 8 //利用StringBuilder的反转方法 9 public static String myReverse(String str){10 StringBuilder sb=new StringBuilder();11 char[] arr=str.toCharArray();12 for (int x=0;x
需求:获取一个字符串在另一个字符串中出现的次数。如: "abkkcdkkefkkskk",获取kk在字符串中出现的次数。
思路:
1.要找的子串是否存在,如果存在获取其出现的位置,这个可以使用indexOf完成。2.如果找到了,那么就记录出现的位置并在剩余的字符串中继续查找该子串,而剩余字符串的起始位是出现位置+子串的长度。3.以此类推,通过循环完成查找,如果找不到就是-1,并且每次找到用计数器记录。1 //"kkabkkcdkkefkkskk",获取kk在字符串中出现的次数 2 class StringTest3 3 { 4 public static void main(String[] args) 5 { 6 String str="kkabkkcdkkefkkskkk"; 7 System.out.println("count="+getCount_1(str,"kk")); 8 9 System.out.println("count="+getCount_2(str,"kk"));10 11 }12 public static int getCount_1(String str,String key){13 int count=0;14 int index=0;15 while((index=str.indexOf(key))!=-1){16 str=str.substring(index+key.length());//把查到key的索引位置加上key的长度,从这往后继续查找,把字串重新赋给str17 count++;18 }19 return count;20 }21 //上面的方法不是很高效,因为每次都切出来子串,这时候内存中的对象太多。所以可以用indexOf()的重载的方法,来提高效率。22 public static int getCount_2(String str,String key){23 int count=0;24 int index=0;25 while ((index=str.indexOf(key,index))!=-1)26 {27 index=index+key.length();//key出现的索引位置加上key的长度再赋给index28 count++;29 }30 return count;31 }32 }
注意:不建议用split()方法来切割计算。因为如果kk在整个字符串的第一个位置的时候这时候切出来的数组就会多一个长度,这个位置上的内容为空。如:“kkabkkcdkkefkks”,这时候的数组是[“ ”,”ab”,”cd”,”ef”,”s”]。
需求:获取两个字符串中最大相同子串。如:"abcwerthelloyuiodef"
思路
1.既然取的是最大子串,先看短的那个字符串是否在长的那个字符串中。如果存在,短的那个字符串就是最大子串。2.如果不是,那么就将短的那个子串进行长度递减的方式去子串,去子串中判断是否存在。如果存在就已找到,就不用再找了。1 public class StringTest{ 2 public static void main(String[] args){ 3 String s1 = "qwerabcdtyuiop"; 4 String s2 = "xcabcdvbn"; 5 String s = getMaxSubstring(s1,s2); 6 System.out.println( "s = " + s); 7 } 8 9 public static String getMaxSubstring(String s1,String s2){10 11 String max = null,min = null;12 max = (s1.length() > s2.length())?s1:s2;13 min = max.equals(s1)?s2:s1;14 15 for(int i = 0; i < min.length(); i++){16 for(int a = 0,b = min.length() - i; b != min.length() + 1; a++,b++){17 String sub = min.substring(a,b);18 if(max.contains(sub))19 return sub;20 }21 }22 return null ;23 }24 }
四、StringBuffer缓冲区
StringBuffer是字符串缓冲区,是一个容器。具有一下特点;
1、长度是可变化的
2、可以直接操作多个数据类型的
3、最终会通过toString方法变成字符串
1、StringBuffer中常用方法
1、构造方法
1 new StringBuffer();2 new StringBuffer(String str);
2、成员方法
(1)、存储
1 StringBuffer append(data);//将指定数据作为参数添加到已有数据结尾处2 StringBuffer append(int index,data);//可以将数据插入到指定index位置上
(2)、删除
1 StringBuffer delete(start,end);//删除缓冲区中的数据,包含start,不包含end2 StringBuffer deleteCharAt(index);//删除指定角标位上的字符
(3)、获取
1 char charAt(int index);//获取指定索引位上的字符2 int indexOf(String str);//获取str第一次出现的索引位3 int lastIndexOf(String str);//反向索引str第一次出现的位置4 int length();//获取StringBuffer的长度5 String substring(int start,int end);//获取字串,包含头,不包含尾
(4)、修改
1 StringBuffer replace(start,end,str);//使用给定 String 中的字符替换此序列的子字符串中的字符2 void setCharAt(int index,char ch);//将指定索引处的字符改为为 ch。 3 StringBuffer insert(int index,String str);//在制定位置插入元素
(5)、反转
1 StringBuffer reverse();
(6)、将缓冲区中指定数据存储到指定的字符数组中
1 void getChars(int srcBegin,int srcEnd,char[] dst,int desBegin);
代码演示:
1 class StringBufferDemo 2 { 3 public static void main(String[] args) 4 { 5 // method_1(); 6 // method_2(); 7 // method_3(); 8 method_4(); 9 10 }11 public static void method_1(){12 StringBuilder sb=new StringBuilder("哈哈哈");13 sb.append("你好").append("不错哦");//append方法返回的还是StringBuffer所以还可以继续调用14 sb.insert(1,"我是黑马");15 16 sb.delete(3,5);17 sb.deleteCharAt(4);//删除指定角标位上的字符18 sb.delete(0,sb.length());//清空缓冲区19 System.out.println(sb.toString());20 }21 public static void method_2(){22 StringBuffer sb=new StringBuffer("嘿嘿嘿,不错哦!");23 System.out.println(sb.charAt(4));//不24 System.out.println(sb.indexOf("不"));//425 System.out.println(sb.length());//826 System.out.println(sb.substring(2,6));//嘿,不错27 }28 public static void method_3(){29 StringBuffer sb=new StringBuffer("字符串缓冲区StringBuffer");30 sb.replace(3,5,"不错");//用给定 String 中的字符替换此序列的子字符串中的字符31 sb.setCharAt(6,'7');32 System.out.println(sb);33 }34 //将字符串进行反转35 public static void method_4(){36 StringBuffer sb=new StringBuffer("www.itheima.com");37 sb.reverse();38 System.out.println(sb);39 }40 }
五、StringBuilder
StringBuilder 和StringBuffer的功能一样,是JDK1.5出现的。
StringBuffer是线程同步的,通常用于多线程。
StringBuilder是线程不同步的,通常用于单线程,它的出现能够提高程序效率。所以以后开发中建议使用StringBuilder,因为效率高,如果多线程可以考虑StringBuffer。
六、基本数据类型对象包装类
1、常见的8种基本数据类型所对应的包装类
该包装对象主要用于基本数据类型和字符串之间的转换。
2、基本数据类型-->字符串
(1)、基本类型数值+""; 如:3+“”等于“3”
(2)、用String类中的静态方法valueOf(基本数据类型值);
(3)、基本数据类型.toString(基本数据类型值); Integer.toString(34);//将34整数变成"34";
3、字符串-->基本数据类型
(1)、使用包装类中的静态方法xxx a=Xxx.parseXxx(String);
int parseInt(String str);
long parseLong(String str);
double parseDouble(String str);
boolean parseBoolean(ture);
只有Character没有parse方法
(2)、如果字符串被Integer进行对象的封装,可以使用另一个非静态的方法:intValue。int num=i.intValue();
(3)、用包装类的静态方法valueOf(String s);
4、整数具备不同的进制转换
(1)、十进制-->其他进制的方法
String toBinaryString(int i);//转成二进制
Stirng toOctalStirng(int i);//转成八进制
String toHexString(int i);//转成十六进制
Stirng toString(int num,int radix);//返回用第二个参数指定基数表示的第一个参数的字符串表示形式。
(2)、其他进制-->十进制方法
int parseInt(String s,int radix);
如:int x = Integer.parseInt("3c",16);//60
代码演示:
1 class Demo 2 { 3 public static void sop(Object obj){ 4 System.out.println(obj); 5 } 6 public static void main(String[] args) 7 { 8 // method_1(); 9 method_2();10 }11 //基本数据类型-->字符串12 public static void method_1(){13 int a=2;14 double d=3.4;15 boolean b=true;16 17 //直接用+""的方法18 sop(a+"");19 sop(d+"");20 sop(b+"");21 22 //用静态方法valueOf()23 sop(String.valueOf(a));24 sop(String.valueOf(d));25 sop(String.valueOf(b));26 27 //包装类的toString()28 sop(Integer.toString(a));29 sop(Double.toString(d));30 sop(Boolean.toString(b));31 }32 33 //字符串-->基本数据类型34 public static void method_2(){35 String s1="2";36 String s2="3.4";37 String s3="true";38 Integer i=5;39 40 //包装类的parseXxx的方法。注:Character没有parseXxx方法41 sop(Integer.parseInt(s1));42 sop(Double.parseDouble(s2));43 sop(Boolean.parseBoolean(s3));44 45 //用包装类中的静态方法:valueOf46 sop(Integer.valueOf(s1));47 sop(Double.valueOf(s2));48 sop(Boolean.valueOf(s3));49 50 //如果字符串被Integer进行对象的封装,可以使用另一个非静态的方法,intValue51 sop(i.intValue());52 }53 }
注意:
Integer m = 128;
Integer n = 128;System.out.println("m==n:"+(m==n));//false。因为超出了byte范围了。
Integer a = 127;
Integer b = 127;System.out.println("a==b:"+(a==b));//结果为true。因为a和b指向了同一个Integer对象。因为当数值在byte范围内容,对于新特性,如果该数值已经存在,则不会在开辟新的空间。
需求:"12 0 99 -7 30 4 100 13"要求对字符串中的数值进行排序。生成一个数值从小到大新字符串。 "-7 0 4 12 13 30 99 100"。
思路:
1.用" "切割字符串,变成字符串数组
2.把字符串数组变成int数组
3.对int数组进行排序
4.把int数组变成字符串
1 /* 2 "12 0 99 -7 30 4 100 13" 3 要求对字符串中的数值进行排序。生成一个数值从小到大新字符串。 4 5 "-7 0 4 12 13 30 99 100" 6 */ 7 import java.util.*; 8 class StringTest5 9 {10 public static void main(String[] args) 11 {12 String str="12 0 99 -7 30 4 100 13";13 System.out.println(toIntArray(str));14 }15 public static String sort(String str){16 String[] arr=str.split(" ");//按照" "切割成字符串数组17 int[] array=new int[arr.length];18 for (int x=0;x