String
String(字符串):最终类:没有子类(共享)
底层是根据字符数组(被private,final共同修饰,一旦字符数组创建,元素值和地址值都无法改变)实现的,导致了字符串创造成功之后是无法改变的-------常量
已经创建的字符串和之后的字符串重复了,就用之前已经创建的字符串-------共享
栈:s1=0x1;
方法区:静态常量池 SringDemo.class
运行常量池:”ab“=0x01
堆:0x01 char[ ]:‘a’ , ‘b’
java中所有的常量都存储在常量池中,字符串也存储在其中,单数字符串底层是由字符组实现的,所以再常量池里,只是在存储指向字符字符数组的地址引用,其他所有的常量直接存储的是真实值
栈-----》方法区运行常量池----》堆
s5=s5+"b"; s6=new StringBuilder("a").append("b").toString();//4 new StirngBuilder(“a”) //1 “b” 1 “ab” 1 //toString() 1
一共创建了5个对象
+拼接和StringBuilder 拼接的效率
空间复杂度:StringBuilder额外开辟的空间更少;
空间复杂度
String[] str = {100个元素};
+拼接
String s=“”; for(int i:str){ s+=i;//一次循环创建3个对象 }
一共创建了301个对象
2.StringBulider拼接字符串
StirngBuilder sb = new StringBuilder(); for(int i:str){ sb.append(i); //依次循环创建1个对象 } //String s = sb.toStirng(); //1个对象
一共创建了102个对象
public class ObjectDemo{ public static void main(String[] args) { //s1指向方法区常量池地址值 String s1= "ab"; //s2指向堆内存地址值 String s2 = new String("ab"); //如果常量池中已经出现的字符串和后面的字符串重复了,就共用一个 String s3="ab"; //等号右边参与操作的都是常量,java在编译时期就会进行优化,计算出最后结果,进行赋值 String s4="a"+"b"; String s5="a"; //字符串底层进行拼接是这样实现的 //底层处理:s6=new StringBuilder("a").append("b").toString(); s5=s5+"b"; //两个指向不同区域,地址值不一样 System.out.println(s1==s2);//false //两个指向同一个字符串常量,地址值一样 System.out.println(s1==s3);//true System.out.println(s1==s4);//true System.out.println(s1==s5);//false System.out.println(s2==s5);//false //堆内存里的不同空间,地址不一样 System.out.println(s5); } }
拼接的毫秒值
StirngBuilder------jdk1.5出现,拼接效率较高,安全
StringBuffer -------jdk1.0出现,拼接效率高,不安全
long start = System.currentTimeMillis();返回的是1970.1.1到今天的毫秒值
public class ObjectDemo{ public static void main(String[] args) { //返回的是1970.1.1到今天的毫秒值 long start = System.currentTimeMillis(); //+拼接 String str=""; for(int i=0;i<10000;i++){ str += "a"; } long end = System.currentTimeMillis(); System.out.println(end-start); } } package test; public class ObjectDemo{ public static void main(String[] args) { //返回的是1970.1.1到今天的毫秒值 long start = System.currentTimeMillis(); //+拼接方法一 // String str=""; // for(int i=0;i<100000;i++){ // str += "a"; // } // //使用StringBuilder拼接 StringBuilder sb = new StringBuilder(); for(int i=0;i<100000;i++){ sb.append(i); //依次循环创建1个对象 } long end = System.currentTimeMillis(); System.out.println(end-start); } } package test; public class ObjectDemo{ public static void main(String[] args) { //回文 abcba String str = new StringBuilder("上海").reverse().toString(); System.out.println(str.toString());//没有地址值输出的功能,只能输出地址值的值 } }
String相关方法
charAt()-----------------------根据下标值,返回字符转对应的字符值
length()-----------------------返回字符串长度
new String(char[ ] cs,int offset,int count)----------把字符数组,转回成一个新的字符串,也可以部分转换
compareTo()------------------------------返回字符串的差值
compareToIgnoreCase()------------------忽略大小写
hashCode();返回的是字符串对象的哈希码值(值只和顺序有关系)
indexOf():返回第一次出现的下标值,如果没找到则返回-1
intern():将对象的地址,直接指向常量池
isEmpty():判断字符串是否是空串
replace():返回一个新串,替换了原串中所有的目标字符
subString():根据给定的下标截取子串进行返回
toLowerCase():转小写 toUpperCase():转大写
trim():去掉字符串前面和后面的空格
valueOf():其他类型转字符串
spilt():切割符:使用正则表达式匹配
遍历字符串
/* 遍历字符串 */ public class ObjectDemo{ public static void main(String[] args) { //创建字符串对象 String str = "sdasd"; //给定字符串(字符数组)下标,返回对应的字符值 // System.out.println(str.charAt(1)); //length()-----表示字符串长度 for(int i=0;i<str.length();i++){ System.out.println(str.charAt(i)); } } }
将字符串转化为字符数组
/* 将字符串转化为字符数组 */ import java.util.Arrays; public class ObjectDemo{ public static void main(String[] args) { //创建字符串对象 String str = "sdasd"; //字符串返回一个新的字符数组 char[] cs = str.toCharArray(); System.out.println(Arrays.toString(cs)); } }
将字符数组转成新的字符转
/* 将字符数组转成新的字符转 */ import java.util.Arrays; public class ObjectDemo{ public static void main(String[] args) { //创建字符串对象 String str = "sdasd"; //字符串返回一个新的字符数组 char[] cs = str.toCharArray(); //String s=new String(cs); //字符数组部分转成字符串 String s=new String(cs,0,4); System.out.println(s); } }
案例:
1.输入一个字符串,统计这个字符串中出现的小写英文字母的次数,数字以及其他字符的次数
/* * 输入一个字符串,统计这个字符串中 * 出现的小写英文字母的次数,数字以及其他字符的次数 * */ public class ObjectDemo{ public static void main(String[] args) { //创建字符串对象 String str = "Sda546sdfas"; //表示小写英文字母出现的次数 int letter=0; //表示数字出现的次数 int num=0 ; //其他字符 int q=0; for(int i=0;i<str.length();i++){ char c = str.charAt(i); //判断是否是小写英文字母a---97,A---65 if(c>='a'&&c<='z'){ letter++; } if(c>='0'&&c<='9'){ num++; } } System.out.println("小写英文字母:"+letter+"数字:"+num); } }
2.输入一个字符串,对字符串中的数字进行求和
public class ObjectDemo{ public static void main(String[] args) { //创建字符串对象 String str = "Sda546sdfas"; //求和变量 int sum=0; //遍历字符串 ,0---48 for(int i=0;i<str.length();i++){ char c=str.charAt(i); if(c>='0'&&c<='9'){ //得到数字的真实值 sum+=(c-'0'); } } System.out.println(sum); } }
3.输入一个字符串,对字符串中的数字进行排序
import java.util.Arrays; public class ObjectDemo{ public static void main(String[] args) { //创建字符串对象 String str = "Sda546sdfas"; //新数组,用于存储数字,之后进行降序 //给定最大长度,保证所有数字都能拿过来 int[] arr = new int[str.length()]; //统计数字的次数 int count=0; //遍历字符串 for(int i=0;i<str.length();i++){ //获取每一个下标对应的字符 char c = str.charAt(i); //判断是否是数字 if(c>='0'&&c<='9'){ //给数组赋值 arr[count]=c-'0'; //数组下标往后移动 count++; } } //对新数组进行缩容操作,保证只排序字符串中的数字 arr= Arrays.copyOf(arr, count); //排序 Arrays.sort(arr); System.out.println(Arrays.toString(arr)); } }
4.输入一个字符串,统计字符串中每个字符出现的次数
public class ObjectDemo{ public static void main(String[] args) { //创建字符串对象 String str = "adfsadf"; //布尔数组 boolean[] bs = new boolean[str.length()]; //初始化 保证初始值都是true true表示未统计 false表示已统计 for(int i=0;i<bs.length;i++){ bs[i]=true; } //遍历数组 for(int i=0;i<bs.length;i++){ //判段是否统计 if(bs[i]){ //拿到字符 char c = str.charAt(i); //统计数 int count=1; //拿字符c和后面的字符进行比较 for(int j=i+1;j<bs.length;j++){ if(c==str.charAt(j)){ bs[j]=false; count++; } } //输出 System.out.println(c+":"+count); } } } }
compareTo()---如果返回值是整数表明前面的字符串大于后面的字符串对象,如果返回的是负数,则后面的字符串较大
public class ObjectDemo{ public static void main(String[] args) { String str1 = "aaqf"; String str2 = "aaf"; //char[] v1={'a','a','q','f'} //char[] v2={'a','a','f'} //将v1和v2两个字符数组,对应位置上的字符进行求差值 //如果差值不为0,就把这个差值当作结果返回 //如果等于0,就把两个字符都往后移动一位,在算出对应的差值,判断 //如果不等于0就把差值输出 //如果其中一个数组,移位结束,就把两个数组的长度差返回 //如果一样则返回0 System.out.println(str1.compareTo(str2)); } }
//字符串字典排序 import java.lang.reflect.Array; import java.util.Arrays; public class ObjectDemo { public static void main(String[] args) { String[] str = { "aqf", "adf", "sgf", "agf" }; for (int i = 1; i < str.length; i++) {// 控制轮数 for (int j = 1; j < str.length - 1; j++) {// 控制参数比较的元素范围 // 判断前面的数是否大于后面的 if (str[j - 1].compareTo(str[j]) > 0) { // 交换两个元素 String temp = str[j = 1]; str[j - 1] = str[j]; str[j] = temp; } } } System.out.println(Arrays.toString(str)); } }
concat:拼接
import java.util.Arrays; public class ObjectDemo { public static void main(String[] args) { String str1 = "asdd"; String str2 = "abc"; //拼接 //底层是通过字符数组的扩容来完成的 //+底层依赖于StringBuilder来拼接的,+可以拼接任意数据 //concat只能拼接字符串---通过底层数组的扩容来完成了字符串之间的拼接 System.out.println(str1.concat(str2)); //asddabc } }
contains:判断参数字符串是否是原串的字串
import java.util.Arrays; public class ObjectDemo { public static void main(String[] args) { String str = "afaf"; //判断参数字符串是否是原串的字串 System.out.println(str.contains("daf")); //false } }
endsWith:判断是否以指定字串结尾
import java.util.Arrays; public class ObjectDemo { public static void main(String[] args) { String str = "afaf"; //判断是否以指定字串结尾 System.out.println(str.endsWith("af")); //true } }
startsWith:判断是否以指定字串开头
import java.util.Arrays; public class ObjectDemo { public static void main(String[] args) { String str = "afaf"; //判断是否以指定字串开头 System.out.println(str.startsWith("a")); //true } }
equals
import java.util.Arrays; public class ObjectDemo { public static void main(String[] args) { String str1 = "afaf"; String str2 = new String("abc"); //先判断两字符串对象地址值是否相等,如果相等就返回true //如果不相等,就将两个字符串转化成两个字符数组 //首先判断类型是否一致,再判断长度是否一致 //如果都一致,一次判断两个字符数组对应的字符是否一致,如果全部一样才返回true //instanceof 左边是对象,右边是类或者接口,判断对象和右边类或者接口的关系 System.out.println(str1.equals(str2)); } }
char c = ’中‘;
上述代码存储在.java文件中,字符c就以utf-8进行编码。此时这个字符就占3个字节。这个.java文件编译成.class文件,.class文件加载到内存中就以utf-8进行编码,这个字符就占了两个字节,当内存执行完成,字符要输出没有指定码表,就按默认的码表进行输出,windows中文版默认为GBK,linux系统默认码表为utf-8.
案例:getBytes()———–如果不指定码表,就按系统默认进行编码
import java.io.UnsupportedEncodingException; public class ObjectDemo { public static void main(String[] args) throws UnsupportedEncodingException { String str = "字符表"; //字符串占城字节数组---没指定码表,按照默认系统平台码 byte[] bs = str.getBytes("utf-8"); System.out.println(bs.length); //按照utf-8编码---9个字节,GBK两个字节表示一个字符 // String s=new String(bs); //解决办法,指定码表 String s=new String(bs,"UTF-8"); System.out.println(s); } }
public class StringText { public static void main(String[] args){ //不同对象调用hashCode()返回值不一样(于环境和程序有关) System.out.println(new Object().hashCode()); System.out.println(new Object().hashCode()); //java中所有的字符串常量就是String的对象 //s是地址值,abc是创建对象 //字符串的值和顺序只要一样,hashCode的值就一样,与对象无关 String s = "abc"; System.out.println("abc".hashCode()); System.out.println(new String("abc").hashCode()); } }
indexOf():返回第一次出现的下标值,如果没找到则返回-1
public class StringText { public static void main(String[] args){ String str = "SADsadasd"; //indexOf返回子串在原串中第一次出现的下标 //没有找到结果,返回-1 //默认从前往后找返回第一次出现的下标 System.out.println(str.indexOf("a")); //可以给定起始下标,从起始下标开始往后找第一次出现的下标 System.out.println(str.indexOf("a",5)); } }
// 拓展:查找与第一个字符串相同的字符串的下标 public class StringText { public static void main(String[] args){ String str = "aADsadasd"; //方法一 //下标 // int index =0; //操作循环 // while(index<str.length()){ // char c = str.charAt(0); // //开始查找,返回第一次出现的下标值 // index=str.indexOf(c+"",index); // //判断返回值是否为-1 // if(index!=-1){ // System.out.println(index++); // }else{ // break; // } // } //方法二 for(int i=0;i<str.length();i++){ String s = "a"; if(s.equals(str.charAt(i)+"")){ int index=str.indexOf("a",i); System.out.println(index); } } } }
intern():将对象的地址,直接指向常量池
public class StringText { public static void main(String[] args){ String str1 = new String("abc"); String str2 = "abc"; //把引用的地址值,直接指向常量池 // str1=str1.intern(); //true str2=str2.intern(); //false System.out.println(str1==str2); } }
isEmpty():判断字符串是否是空串
public class StringText { public static void main(String[] args){ String str=""; String str1 = new String("adas"); System.out.println(str.isEmpty()); //true System.out.println(str1.isEmpty()); //false } }
replace():返回一个新串,替换了原串中所有的目标字符
public class StringText { public static void main(String[] args){ String str = "lkfdjffg"; //会替换原串中所有目标字符,对原串没有影响 System.out.println(str.replace('f', '+')); //lk+dj++g System.out.println(str); //lkfdjffg } }
subString():根据给定的下标截取子串进行返回
public class StringText { public static void main(String[] args){ String str = "lkfdjffg"; //返回从起始下标截取的字串,截取的时候包括截取下标 //如果给出的下标值等于字符串长度,返回空串 System.out.println(str.substring(8)); //可以根据给定起始下标和结束下标进行截取子串 System.out.println(str.substring(4,8)); } }
toLowerCase():转小写 toUpperCase():转大写
public class StringText { public static void main(String[] args){ String str = "ADASDFfdjffg"; //转小写(英文) String str1=str.toLowerCase(); System.out.println(str1); //转大写(英文) String str2 =str1.toUpperCase(); System.out.println(str2); } }
trim():去掉字符串前面和后面的空格
public class StringText { public static void main(String[] args){ String str = " ADASD\tFfdjffg "; System.out.println(str+"a") ; // ADASD Ffdjffg a //前面和后面空格全部去掉----掐头去尾 System.out.println(str.trim()+"a"); //ADASD Ffdjffga } }
valueOf():其他类型转字符串
public class StringText { public static void main(String[] args){ boolean b = false; //布尔类型数据转字符串----Java提供了所有数据类型转字符串二点重写 String str = String.valueOf(b); System.out.println(str); //false } }
spilt():切割符:使用正则表达式匹配
import java.util.Arrays; public class PatternDemo { public static void main(String[] args) { String str="7to567m7an6dja4ck"; //正则匹配的信息 --- 变为切割符 //以数字进行切割 //如果多个切割符同时出现在了一起,会切除空串 //如果多个切割符一起出现在了最前面,也会切出空串 String[] str1 = str.split("\\d"); System.out.println(Arrays.toString(str1)); //[, to, , , m, an, dja, ck] } }
扩展:
public class StringText { public static void main(String[] args){ int[] arr = {1,2,3}; //返回地址值----String.valueOf(arr) //valueOf()底层调用Object的toString() -----拼接地址值 System.out.println(arr); //[I@659e0bfd char[] cs={'1','a','5'}; //没有调用Object的toString(),依次打印元素 System.out.println(cs); //1a5 System.out.println(cs.toString()); //[C@2a139a55 } }