包装类
出现的原因:
Java为纯面向对象语言(万物皆对象),而8种基本数据类型不能创建对象,破坏了Java为纯面向对象语言的特征,所以Java又给者8种基本数据类型分别匹配了对应的类,这种叫做包装里/封装类
基本数据类型 | 引用数据类型 | 继承 |
---|---|---|
byte | Byte | extends Number extends Object |
short | Short | extends Number extends Object |
int | Integer | Integer extends Number extends Object |
long | Long | extends Number extends Object |
float | Float | extends Number extends Object |
double | Double | extends Number extends Object |
char | Character | extends Object |
boolean | Boolean | extends Object |
注意:
- 数值型都继承Number
- int的包装类Integer
- char的包装类Chararcter
箱:
装箱:基本数据类型 —>包装类
int i=100; Integer integer=Integer.valueOf(i);//封箱 System.out.println(integer);
拆箱:包装类-----> 基本数据类型
Integer integer=new Integer(100); int i=integer.intValue();//拆箱 System.out.println(i);
自动装箱:基本数据类型 -----> 包装类
int i=100; Integer integer=i;//自动装箱(底层实现:Integer.valueOf(i);) System.out.println(integer);
自动拆箱:包装类----->基本数据类型
Integer integer=new Integer(100); int i=integer;//自动装箱(底层实现:integer.intValue();) System.out.println(i);
注意:JDK1.5版本的新特性:自动装箱、自动拆箱
**应用场景:**集合(类似数组的容器),但是集合只能存引用数据类型,如果想存储基本数据类型,就可以把基本数据类型转换为对应的包装类对象
public class Test01{
public static void main(String[] args){
/**
知识点;包装类
需求:把字符串数组{"1","2","3","4","5"}
*/
String[] isstr={"1","2","3","4","5"};
int[] is=new int[isstr.length];
for(int i=0;i<is.length;i++){
//1.将String转换为Integer对象
//2.Integer对象自动拆箱成int数据
int num=Integer.valueOf(isstr[i]);
is[i]=num;
}
for(int element:is){
System.out.println(element);
}
}
}
string类的常用方法
注意:String是一个不可变的类,即一旦一个String对象被创建,包含在这个对象中的字符序列是不可改变的,直到该对象被销毁
public class Test{ public static void main(String[] args){ String str="123abc"; str =str.concat("DEF123");//在此字符串末尾追加字符串,并返回新的字符串 str =str.substring(2);//从开始下标处截取到字符串末尾,并返回新的字符串 str =str.substring(1,7);//从开始小标出(包含)截取到结束下标处(不包含),并返回新的字符串 str =str.toUpperCase();//转大写,并返回新的字符串 str =str.toLowerCase();//转小写,并返回新的字符串 str =" 123 a bc D EF 123"; str =str.trim();//去除首尾空格,并返回新的字符串 str =str.replace('2','-');//替换字符,并返回新的字符串 str =str.replaceFirst("3","榮十一");//替换第一个出现的字符串,并返回新的字符串 str =str.replaceAll("1","xxx");//替换字符串,并返回新的字符串 str =str.replaceAll(" ","");//替换字符串,并返回新的字符串 System.out.println("判断两个字符串内容是否相同:(区分大小写)" + str.equals("xxx-榮十一abcDEFxxx-3")); System.out.println("判断两个字符串内容是否相同:(不区分大小写)" + str.equalsIgnoreCase("XXX-榮十一ABCdefxxx-3")); System.out.println("判断此字符串是否以某个字符串开头:" + str.startsWith("xxx")); System.out.println("判断此字符串是否以某个字符串结尾:" + str.endsWith("-3")); System.out.println("查询此字符串第一次在目标字符串中的下标:" + str.indexOf("-")); System.out.println("查询此字符串最后一次在目标字符串中的下标:" + str.lastIndexOf("-")); System.out.println("获取指定下标上的字符:" + str.charAt(4)); //xxx-榮十一abcDEFxxx-3 System.out.println(str); } }
案例:
public class Test{ public static void main(String[] args){ //将其他类型转换为字符串 int i=100; System.out.println(String.valueOf(i)); boolean bool =true; System.out.println(String.valueOf(bool)); } }
public class Test{ /** (1),“@”不能在第一位 (2),“.”不能在最后一位 (3),“@”和“.”中间应该有字符 (4),***@***.*** */ public static void main(String[] args){ String email="rongshiyi@qq.com"; int index1=email.indexOf("@"); int index2=email.indexOf("."); if(index1==0||index2==email.length()-1||(index2-index1)<=1){ System.out.println("邮箱格式错误") } } }
面试题一:
下面代码创建几个String对象(考点:常量池种的值必须是唯一的)
String str1="abc"; String str2="abc";
答案:一个
原因:设abc在常量池中的地址为0x11,只是被调用了两次,但是值只有一个
面试题二:
下面代码创建几个String对象(考点:常量池中的值必须是唯一的)
String str1=new String("abc"); String str2=new String("abc");
答案:三个
原因: String中abc为一个,str1给new了一个,str2被new了一个,共三个
深入String创建对象问题
public classTest{ public static void main(String[] args){ String str1="abc"; String str2="abc"; System.out.println(str1==str2);//true //两个常量字符串直接在编译时拼接 String str3="ab"+"c"; System.out.println(str3==str1);//true //两个常量字符串直接在编译时拼接 final String s1="ab"; final String s2="c"; String str4=s1+s2; System.out.println(str4==str1);//true //两个变量字符串拼接底层是创建StringBuider'对象 String s3="ab"; String s4="c"; String str5=s3+s4;//new StringBuilder(s3).append(s4).toString(); System,out,println(str5==str1);//false } }
StringBuffer
StringBuffer代表可变的字符序列被称之为:字符串缓冲区
工作原理:预先申请一块内存,存放字符序列,如果字符序列满了,会催促下该百年缓存区的大小,以容纳更多的字符序列
StringBuffer是可变对象,这个是String最大的不同
**继承关系:**StringBuffer extends AbstractStringBuilder
public class Test{ public static void main(Stringp[] args){ //默认字符串缓冲区:16个字符 StringBuffer sb1=new StringBuffer(); //自定义字符串缓冲区:100个字符 StringBuffer sb2=new StringBuffer(100); //自定义字符串缓区:"123abc".length()+16:22个字符 StringBuffer sb3=new StringBuffer("123adc"); sb3.append("DEF123");//在末尾追加字符串 sb3.insert(6,"xxx");//在指定下标处插入字符串 sb3.setCharAt(3,'A');//替换指定下标上的字符 sb3.replace(6,9,"榮十一");//从下标处开始替换到结束下标处(不包含)的字符串 sb3.deleteCharAt(1);//删除指定下标上的字符 sb3.delete(5,8);//从下标处删除到结束处(不包含)的字符串 sb3.reverse();//反转字符串 //321FEDcdA31 System.out.println(sb3); } }
StringBuilder
与上面StrubgBuffer相同
StringBuffer VS StringBuilder
相同点:使用上一模一样,因为他们都继承于AbstractStringBuilder
StringBuffer:线程安全的,效率低
StringBuilder:线程不安全的,效率高
字符串频繁拼接问题
经验:频繁的拼接字符串请使用StringBuider或StringBuffer
public class Test{ public static void main(String[] args){ //低效率: //获取来自1970.1.1 0:0:0到现在的毫秒数 long startTime=System.currentTimeMillis(); String str="沝"; for(int i=0;i<5000000;i++){ str+="沝"; } long endTime =System.currentTimeMills(); System.out.println("消耗时长:"+(endTime-startTime)); //高效率 long startTime1=System.currentTimeMillis(); StringBuilder str1=new StringBuilder("沝"); for(int i=0;i<5000000;i++){ str1.append("沝"); } long endTime1=System.currentTimeMillis(); System.out.println("消耗时长"+(endTime1-startTime1)); } }