第八章 常用类
8.1 基本数据类型的包装类
包装类:为了实现基本类型和对象之间的相互转化。
8.1.1 包装类的基本知识
8个基本数据类型对应的类统称为包装类。
byte short long double float boolean char int
Byte Short Long Double Float Boolean Character Integer
除了Boolean,Character类外,
其他类都是"数字型",都是抽象类java.lang.Number的子类,必须实现他的抽象方法。
Number类提供的抽象方法有:
intValue(),LongValue(),floatValue(),doubleValue(),
这意味着所有数字型的包装类都可以相互转型。
8.1.2 包装类的用途
主要用途包括两种:
1,作为和基本数字类型对应的类型存在,方便涉及到对象的操作,eg:Object[],集合
2,包含每种基本数据类型的相关属性,以及相关操作方法。
这些方法的作用是在基本数据类型和包装类对象,字符串之间相互转换。
public class Test{
void testInteger(){
//基本类型转化为Integer对象
Integer int1 = new Integer(10);
Integer int2 = new Integer.valueOf(20);//官方推荐写法
//Integer对象转换为int
int a = int1.intValue();
//字符串转换为Integer对象
Integer int3 = Integer.parseInt("334");
Integer int4 = new Integer("999");
//Integer对象转化成字符串
String str1 = int3.toString();
//一些常见int类型 相关的常量
System.out.println("int能表示的最大整数:"+Integer.MAX_VALUE);
}
public static void main(String[] args){
Test test = new Test();
test.testInteger();
}
}
8.1.3 自动装箱和彩拆箱
指的是在基本数据类型和包装类之间进行自动转换
1,自动装箱(autoboxing)
java自动将基本数据类型转换为相应的包装类对象
2,自动拆箱(unboxing)
相应的包装类对象自动转换为基本数据类型
总结起来就是:
自动装箱过程是通过调用包装类的valueOf方法来实现的
自动拆箱过程是通过调用包装类的***Value()方法实现。
(***代表对应的基本数据类型)
8.1.4 包装类的缓存问题
整形,char类型所对应的包装类在自动装箱时,
对于-128~127之间的值会进行缓存处理,其目的是提高效率。
缓存处理的原理:
如果数据在-128~127之间,那么类加载时,就已经为该区间的每个数值创建了对象,
并将者256个对象存放到一个名为cache的数组中,每当自动装箱过程发生时,
(或手动调用valueOf()时),就会先判断该数据是否在该区间,
如果在,则直接获取数组中对应的包装类对象的引用;
如果不在则通过new调用包装类的构造器来创建对象。
小结:自动装箱调用valueOf()方法;
自动拆箱调用***Value()方法
包装类在自动装箱时为了提高效率,对于-128~127之间的值进行缓存处理。
超多范围后对象之间不能再使用 == 进行数值比较,而应使用equals方法。
8.2 字符串相关类
String类,对象代表不可变的字符序列。
StringBuilder类,StringBuffer类,代表可变字符序列
是三个与字符串相关的类
8.2.1 String类
1,String类代表不可变的Unicode字符序列,String类的对象称之为不可变对象。
不可变对象内部的成员变量的值无法改变。
源码中他的字符串内容全部存储到value[]数组中,而变量value是final类型的,
也就是常量,只能赋值一次,这就是不可变的典型定义方式。
2,String类的常用方法:
.创建并返回一个新String对象的方法:
concat(),replace(),substring(),toLowerCase(),toUpperCase(),trim().
.提供查找功能的方法:
endWith(),startsWith(),indexOf(),lastIndexOf()
.提供比较功能的方法:
equals(),equalsIgnoreCase(),compareTo();
.其他方法:
charAt(),lendth().
8.2.2 StringBuffer和StringBuilder
1,类似均代表可变的字符串序列,他们都是AbstractStringBuilder的子类。
源码内部value[] 数组没有final修饰,随时可以修改。
2,两者区别
StringBuffer:jdk1.0提供,线程安全,做线程同步检查,效率低 。
StringBuilder:jdk1.5提供 ,线程不安全,不做线程同步检查,效率高,建议使用。
3,常用方法:
.重载的public StringBuilder append(...)方法
为该StringBuilder对象添加字符序列,任然返回自身对象。
.方法public StringBuilder delete(int start,int end)
删除从start开始到end-1为止的一段字符序列,任然返回自身对象。
.public StringBuilder deleteCharAt(int index)
移除此序列指定位置上的char,仍然返回自身对象。
.重载的public StringBuilder insert(...)方法
为该StringBuilder对象在指定位置插入字符序列,任然返回对象自身。
.方法public StringBuilder reverse()
用于将字符序列逆序,任然返回自身对象。
.public String toString ()
返回此序列中数据的字符串表示形式
4,和String类含义类似的方法有
public int indexOf(String str);
public int indexOf(String str,int fromIndex);
public String substring(int start);
public String substring(int start,int end);
public int length();
char charAt(int index);
8.2.3 不可变和可变字符使用陷阱
String一经初始化就不会再改变其内容了,
对String的操作其实是对其副本的操作,原来的字符串一点都没有改变。
使用过程中若多次执行改变串内容的操作,
会导致大量的字符串对象存在于内存中,降低效率。
如果将这样的操作放到循环中,会极大的影响程序的时间和空间性能,
甚至造成服务器的崩溃。
StringBuilder和StringBuffer类是对原字符串本身操作,
对字符串修改不产生副本,或产生少量副本,因此在循环中使用。
小结:
String:不可变字符序列
StringBuffer:可变字符序列 ,线程安全,效率低
StringBuder: 可变字符序列 ,线程不安全,效率高(一般用它)。
8.3 时间处理相关类
计算机世界的基准时间 1970,1,1 00:00:00 每个度量单位是毫秒
Java用long类型的变量来表示时间;
long now = System.currentTimeMillis();
获得现在时刻的"时刻数值" 。
8.3.1 Date时间类(java.util.Date)
Date()
分配一个Date对象,并初始化此对象为系统当前的日期和时间,可以精确到毫秒。
Date(long date)
分配Data对象并初始化此对象,以表示自从基准时间以来的指定毫秒数。
booleanbefore(Date when)
测试此日期是否在指定日期之前
boolean equals(Object obj)
比较两个日期的相等性
long getTime()
返回至标准时间以来,此Date对象表示的毫秒数
String toString()
把此Date转化为 dow mon dd hh:mm:ss zzz yyy 形式的String。
8.3.2 DateFormat类和SimpleDateFormat类
1,作用:
DataFormat类的作用是将时间对象转化成指定格式的字符串,
反之则将指定格式的字符串转化为时间对象。
DataFormat是一个抽象类,一般使用他的子类SimpleDateFormat类来实现。
//DateFormat类和SimpleDateFormat类的使用
public class TestDateFormat{
public static void main(String[] args) thows ParseException{
//new出SimpleDateFormat对象
SimpleDateFormat s1 = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
SimpleDateFormat s2 = new SimpleDateFormat("yyyy-MM-dd");
//将时间对象转化成字符串
String daytime = s1.format(new Date());
System.out.println(daytime);
System.out.println(s2.format(new Date())) ;
System.out.println(new SimpleDateFormat("hh:mm:ss").format(new Date()));
//将符合指定格式的字符串转换成时间对象,字符串格式需要和指定格式一致
String time = "2007-10-9";
Date date = s2.parse(time);
System.out.println("date1:"+date);
time = "2007-10-9 20:23:45";
date = s1.parse(time);
System.out.println("date2:"+date);
}
}
时间格式字符
G:Era标识符 a:Am/Pm标记
y:年 H:一天中的小时数(0-23)
M:年中的月份Month k:一天中的小时数(0-24)
w:年中的周数 Number K:am/pm中的小时数(0-11)
W:月份中的周数 h:am/pm中的小时数(0-12)
D:年中的天数 m:小时中的分钟数
d:月份中的天数 s:分钟中的秒数
F:月份中的星期 S:毫秒数
E:星期中的天数 z:General时区
Z:时区
8.3.3 Calender日历类
月份的表示中:
一月是0,二月是1... 十二月是11。习惯上使用全大写的单词而不是数字
//可视化日历表编写
略
8.4 Math类
1,Math类的常用方法如下:
abs:绝对值
acos,asin,atan,cos,sin,tan:三角函数
sqrt:平方根
pow(double a,double b):a的b次幂
max(double a,double b):取大值
min(double a,double b):取小值
ceil(double a):大于a的最小整数
floor(double a):小于a的最大整数
random();返回0.0到1.0的随机数
long round(double a);double型的数据a转化为long型(四舍五入)
toDegrees(double angrad);弧度转化为角度
toRadians(double angdeg);角度转化为弧度
专门用来生成随机数的类Random类。
Math.random()底层调用的就是Random的nextDouble()方法。
8.5 File类
file类用来代表文件和目录,开发中的读取,生成,删除,修改文件时常用。
8.5.1 File类的基本用法
1,File类的常见构造器
public File(String pathname);
如果pathname是相对路径,则当前路径是指在系统属性user.dir所指定的路径。
//使用File类创建文件
public static TestFile{
public static void main(String[] args) throws Exception{
System.out.println(System.property("user.dir"));
File f = new File("a.txt");//相对路径默认放到user.dir目录下面
f.creatNewFile();//创建文件
File f2 = new File("d:/b.txt")//绝对路径
f2.creatNewFile();
}
}
2,File类访问属性的方法列表
public boolean exists();
判断file是否存在
public boolean isDirectory();
判断file是否是目录
public boolean isFile();
判断file是否是文件
public long lastModified();
返回file最后的修改时间
public long length();
返回file大小
public String getName();
返回文件名
public String getPath();
返回文件的目录路径
3,File类创建文件或目录的方法
creatNewFile();
创建新的file
delete();
删除file对应的文件
mkdir();
创建一个目录:中间某个目录缺失则创建失败
mkdirs();
创建一个目录:中间某个文件缺失则创建该缺失目录
8.5.2 递归遍历目录结构和数状展现
略
8.6 枚举
枚举的定义包括枚举的声明和枚举的定义
枚举定义格式:
enum 枚举名{
枚举体(常量列表)
}
枚举实质上还是一个类,每个被枚举的成员实质上就是枚举类型的实例,
他们默认都是由 public static final 修饰的,可以直接通过枚举类型名使用他们。
枚举的使用:
当需要定义一组常量时,可以使用枚举类型;
尽量不要使用枚举的高级特性。
public class TestEnum{
public static void main(String[] args){
//枚举遍历
for(Weak k:Weak.value()){
System.out.println(k);
}
//switch语句中使用枚举
int a = new Random().nextInt(4);//生成0,1,2,3,的随机数
switch (Season.value()[a]) {
case SPRING;
System.out.println("春天");
break;
case SUMMER;
System.out.print("夏天");
break;
case AUTUMN;
System.out.println("秋天");
break;
case WINDTER;
System.out.println("冬天");
break;
}
}
}
//季节
enum Season{
SPRING,SUMMER,AUTUON,WINDTER
}
//星期
enum Week{
SUNDAY,MONDAY,TUESDAY,WEDNESDAY,THURSDAY,FRIDAY,STATURDAY
}