包装类
8种基本数据类型
byte short int long double float boolean char
Byte Short Integer Long Double Float Boolean Character
包装类:对基本数据类型进行封装,提供对应类型的API(含有各种函数)
包装类的变量缺省值为null,基本数据类型为0(表示数字的数据类型)
1)缓冲区
Byte Short Integer Long 都有一个缓冲区 -128~127
Character 缓冲区 ASCII
Float Double Boolean 没有缓冲区
2)基本数据类型和包装类
int a=10;
Integer b=10;自动装箱 valueOf(int x)
Integer c=new Integer(10);
int类型间进行比较,比较的数值 返回的是ture
a==b int类型和Integer类间进行比较时,自动拆箱,比较的是数值
自动装箱的Integer类进行比较时,比较的是内存地址 由于都在缓冲区,返回ture
b==c Integer类间进行比较,比较的是内存地址 返回false
3)包装类的组成
Integer包装类的部分代码:
public final class Integer {
//缓冲区
private static class IntegerCache {
static final int low = -128;//缓存的最小值
static final int high;//缓存的最大值
static final Integer cache[];//缓存数组
static { //静态初始化块,用于初始化缓存
// high value may be configured by property
int h = 127;high = h;//默认最大值为127
cache = new Integer[(high - low) + 1];//初始化缓存数组
int j = low;
for(int k = 0; k < cache.length; k++)//填充缓存数组
cache[k] = new Integer(j++);
// range [-128, 127] must be interned (JLS7 5.1.7)
assert IntegerCache.high >= 127;//确保值>=127,即[-128,127]内的整数被缓存
}
private IntegerCache() {}//私有构造函数,防止实例化
}
//返回指定整数值的Integer实例
public static Integer valueOf(int i) {
//如果值在缓存区范围内,返回缓存中的实例
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);//否则创建新的Integer实例
}
//存储整数值的字段
private final int value;//值
//返回存储的整数值
public int intValue() {
return value;
}
}
设置缓存区,减少频繁构建小整数的开销,提高性能
因此 当创建 整数类型对应包装类 直接赋值时,若在-127~128范围内放到缓冲区 ,否则创建新的Integer实例。
4)自动拆箱和自动装箱
//自动装箱
public static Double valueOf(double d){
return new Double(d);
}
//自动拆箱
public double doubleValue(){
return value;
}
进行包装类赋值时,自动装箱
进行包装类和基本数据类型比较时,包装类自动拆箱,进行数值比较
5)Character缓冲区
private static class CharacterCache {
private CharacterCache(){}
static final Character cache[] = new Character[127 + 1];
static {
for (int i = 0; i < cache.length; i++)
cache[i] = new Character((char)i);
}
}
范围为ASCII
Character a = "椿";
Character b = "椿";
a==b 进行地址比较,因为超出范围,所以创建新的实例,地址不同,返回false
包装类一般进行值比较时使用equals更方便
String类
不可变字符串
- 字符串比较
s1==s2 比较的是字符串地址
s1.equals(s2) 比较的是字符串
- 字符串的定义
定义:字符数组
String s1 = "";
String s2 = new String();
//equals结果为true
String s3 = new String("abc")
String s3 = new String(new char[]{'a','b','c'});
String s4 = new String(new byte[]{97,98,99});
String s5 = new String(new char[]{'a','b','c','d'},0,3);//从第0位开始,共3个
//equals结果为true
- 字符串编码
String s = "鸣潮";
//转换为字节数组
byte[] bytes1 = s.getBytes();//此处未提供编码方式,缺省值为文件编码utf-8
byte[] bytes2 = s.getBytes(Charset.forName("GBK"));
//转换为字符串
String s1 = new String(bytes1,Charset.forName("utf-8"));
String s2 = new String(bytes1,Charset.forName("GBK"));
使用System.out.println("Arrays.toString(bytes)")输出数值拼接形成的字符串等,结果为
bytes1:[-23, -72, -93, -26, -67, -82]
bytes2:[-61, -7, -77, -79]
s1: 鸣潮
s2: 楦f疆
utf-8编码
- 字符串常量池(缓存区)和intern
字符串有一个缓冲区:字符串常量池
调用intern方法可以保存到缓冲区,没有就保存,有就返回
💡
字面量??
String a = "abc";
String b = new String("abc");
String c = new String("abc").intern//创建新的String实例并将字符串放到缓冲区
// == 进行地址比较,a,c 都在字符串常量池,是同一地址
// == b是创建的新实例,不和a,c在同一地址
String s = "a"+"bc";//直接得出结果,在缓冲区
String s1 = "ab";
String s2 = "c";
String s0 = s1 + s2;//需要在上下文获取结果,新创建了实例
// s == s0 进行地址比较,返回false
- 可变字符串
StringBuffer StringBuilder
StringBuffer 线程安全 JDK1.0时引用 后被StringBuilder取代
大部分方法用synchronized修饰 (synchronized确保同一时间只有一个线程可以执行)
StringBuilder 线程不安全 JDK1.5时引用 相比StringBuffer高效
没有synchronized
- 连接字符串 可变字符串和不可变字符串间的比较
//String类连接
String s = "a";
for (int i = 0 ; i < 1000 ; i++){
s += "a";
}
//StringBuilder类连接
StringBuilder sb = new StringBuilder("a");
for (int i = 0 ; i < 1000 ; i++){
sb.append("a");
}
//s.equals(sb.toString)进行比较,sb直接调用返回的是内存地址
通过 System.currentTimeMillis()函数调用系统时间,计算时间进行比较
String类连接的时间明显大于StringBuilder类连接
String类连接过程
//因为 String为不可变字符串,每次连接都会创建一个新的字符串,申请堆空间 并调用sb.toSting
StringBuilder sb = new StringBuilder();//创建新实例
sb.append("a");
a.sb.toString();
toString函数
public String toString(){
//Create a copy, don't share the array
return new String(value, 0, count);
}
日期类
//!以下代码不可直接运行
Date date = new Date;
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);//设置时间
calendar.get(Calendar.YEAR);//返回值为YEAR
//MONTH(从0开始) DATE HOUR_OF_DAY(24小时制,HOUR为12小时制) MINUTE SECOND
calendar.add(Calendar.DATE, 10)
//格式化
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")//新建sdf格式
String format = sdf.format(time);//格式化日期和时间
Date parse = sdf.parse(timeStr);//解析字符串为Date对象
Sytem.out.println(date.toString);//显式调用toString函数,打印时,直接打印date是隐式调用
函数类
Math中所有函数都是静态方法
Math.max(1,2,3)
max min ceil向上取整 floor向下取整 round四舍五入
随机数类
Random random = new Random();
double d = random.nextDouble();//0-1间的随机数
int i = random.nextInt();//随机数
int i = random.nextInt(10);//整数0-9取随机数