包装类
含义:基本数据类型对应的类
* 出现原因:
* Java为纯面向对象语言(万物皆对象),而8种基本数据类型不能创建对象,破坏了Java为纯面向对象
* 语言的特征,所以Java又给这8种基本数据类型分别匹配了对应的类,这种叫做包装里/封装类
* 继承关系:
* 基本数据类型 引用数据类型
* byte Byte extends Number extends Object
* short Short extends Number extends Object
* int 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
应用场景:集合(类似数组的容器),但是集合只能存引用数据类型,如果想存储基本数据类型,就可以把基本数据类型转换为对应的包装类对象
package com.dream.package_class;
public class Test01 {
public static void main(String[] args) {
/**
* 注意:
* 1.数值型都继承Number
* 2.int的包装类Integer
* 3.char的包装类Character
*
* 装箱:基本数据类型 -> 包装类
* 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);
JDK1.5的新特性:自动装箱、自动拆箱
自动装箱:基本数据类型 -> 包装类
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);
}
}
案例一:
package com.dream.package_class;
public class Test02 {
public static void main(String[] args) {
/**
* 知识点:包装类
* 需求:把字符串数组{"1","2","3","4","5"}转换为int数组
*/
String[] ss = {"1","2","3","4","5"};
int[] is = new int[ss.length];
for (int i = 0; i < is.length; i++) {
//1.将String转换为Integer对象
//2.Integer对象自动拆箱成int数据
int num = Integer.valueOf(ss[i]);
is[i] = num;
}
for (int element : is) {
System.out.println(element);
}
}
}
1.1深入包装类低层源码
总结:
Integer底层有个缓存类,缓存类中有个数组,存储了-128~127的Integer对象
Integer.valueOf(num)底层会判断num是否在-128~127这个区间,如果在内就从缓存
数组中获取数据,如果不在这个区间就new对象
自己写个MyInteger类:
package com.dream.package_class;
public class MyInteger {
private int value;
public MyInteger(int value) {
this.value = value;
}
public static MyInteger valueOf(int i){
if(i >= MyIntegerCache.low && i <= MyIntegerCache.high){
return MyIntegerCache.cache[i - MyIntegerCache.low];
}
return new MyInteger(i);
}
//MyInteger的缓冲类
private static class MyIntegerCache{
private static final int low = -128;
private static final int high = 127;
private static final MyInteger[] cache;
static{
//初始化缓冲数组
cache = new MyInteger[high - low + 1];
int j = low;
for (int i = 0; i < cache.length; i++) {
cache[i] = new MyInteger(j++);
}
}
}
@Override
public String toString() {
return Integer.toString(value);
}
}
测试类:
package com.dream.package_class;
public class Test03 {
public static void main(String[] args) {
Integer integer1 = Integer.valueOf(100);
Integer integer2 = Integer.valueOf(100);
System.out.println(integer1 == integer2);//true
Integer integer3 = Integer.valueOf(200);
Integer integer4 = Integer.valueOf(200);
System.out.println(integer3 == integer4);//false
System.out.println(integer1);
System.out.println(integer2);
System.out.println(integer3);
System.out.println(integer4);
System.out.println("-------------");
MyInteger myInteger1 = MyInteger.valueOf(100);
MyInteger myInteger2 = MyInteger.valueOf(100);
System.out.println(myInteger1 == myInteger2);//true
MyInteger myInteger3 = MyInteger.valueOf(200);
MyInteger myInteger4 = MyInteger.valueOf(200);
System.out.println(myInteger3 == myInteger4);//false
System.out.println(myInteger1);
System.out.println(myInteger2);
System.out.println(myInteger3);
System.out.println(myInteger4);
}
}
2、String类的常用方法
注意:String是一个不可变的类, 即一旦一个String对象被创建, 包含在这个对象中的字符序列是不可改变的, 直至该对象被销毁。
package com.dream.string_class;
public class Test01 {
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 bcD 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);
}
}
package com.dream.string_class;
public class Test02 {
public static void main(String[] args) {
/**
* 知识点:String类的常用方法
* 注意:String是一个不可变的类, 即一旦一个String对象被创建, 包含在这个对象中的字符序列是不可改变的, 直至该对象被销毁。
*/
//将其他类型转换为字符串
int i = 100;
System.out.println(String.valueOf(i));
boolean bool = true;
System.out.println(String.valueOf(bool));
}
}
2.1、深入String创建对象问题
package com.dream.string_class;
public class Test04 {
public static void main(String[] args) {
/**
* 知识点:深入String创建对象问题
*
* 面试题1:下列代码创建几个String对象(考点:常量池中的值必须是唯一的)
* String str1 = "abc";
String str2 = "abc";
答案:一个
面试题2:下列代码创建几个String对象(考点:常量池中的值必须是唯一的)
String str1 = new String("abc");
String str2 = new String("abc");
答案:三个
*/
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
//两个变量字符串拼接底层是创建StringBuilder对象
String s3 = "ab";
String s4 = "c";
String str5 = s3+s4;//new StringBuilder(s3).append(s4).toString()
System.out.println(str5 == str1);//false
}
}
2.2、StringBuffer
package com.dream.stringbuffer_class;
public class Test01 {
public static void main(String[] args) {
/**
* 知识点:StringBuffer
*
* StringBuffer代表可变的字符序列。
* StringBuffer称为字符串缓冲区,
* 它的工作原理是:
* 预先申请一块内存,存放字符序列,
* 如果字符序列满了,会重新改变缓存区的大小,以容纳更多的字符序列。
* StringBuffer是可变对象,这个是String最大的不同
*
* 继承关系:StringBuffer extends AbstractStringBuilder
*/
//默认字符串缓冲区:16个字符
//StringBuffer sb = new StringBuffer();
//自定义字符串缓冲区:100个字符
//StringBuffer sb = new StringBuffer(100);
//自定义字符串缓冲区:"123abc".length() + 16 : 22个字符
StringBuffer sb = new StringBuffer("123abc");
sb.append("DEF123");//在末尾追加字符串
sb.insert(6, "xxx");//在指定下标处插入字符串
sb.setCharAt(3, 'A');//替换指定下标上的字符
sb.replace(6, 9, "用良心做教育");//从开始下标处(包含)替换到结束下标处(不包含)的字符串
sb.deleteCharAt(1);//删除指定下标上的字符
sb.delete(5, 11);//从开始下标处(包含)删除到结束下标处(不包含)的字符串
sb.reverse();//反转字符串
//321FEDcbA31
System.out.println(sb);
}
}
2.3、StringBidder
与StringBuffer 使用方法一样
区别:StringBuffer:线程安全的,效率低
StringBuilder:线程不安全的,效率高
2.4、字符串频繁拼接问题
package com.dream.stringbuilder_class;
public class Test02 {
public static void main(String[] args) {
/**
* 知识点:字符串频繁拼接问题
*
* 经验:频繁的拼接字符串请使用StringBuilder或StringBuffer
*/
// //获取自1970.1.1 0:0:0到现在的毫秒数
// long startTime = System.currentTimeMillis();
// String str = "林成";
// for (int i = 0; i < 50000; i++) {
// str += "小可爱,皇冠给你带";
// //str = str + "小可爱,皇冠给你带"
// //str = new StringBuilder(str).append("小可爱,皇冠给你带").toString();
// }
// long endTime = System.currentTimeMillis();
// System.out.println("消耗时长:" + (endTime-startTime));//5746
//获取自1970.1.1 0:0:0到现在的毫秒数
long startTime = System.currentTimeMillis();
StringBuilder sb = new StringBuilder("林成");
for (int i = 0; i < 50000; i++) {
sb.append("小可爱,皇冠给你带");
}
long endTime = System.currentTimeMillis();
System.out.println("消耗时长:" + (endTime-startTime));//5
}
}