1、为什么需要包装类
Java并不是纯面向对象的语言。(中庸、效率)Java语言是一个面向对象的语言,但是Java中的基本数据类型却是不面向对象的。但是我们
在实际使用中经常需要将基本数据类型转化成对象,便于操作。比如:集合的操作,使用Object类型接收任意类型的数据等,这时,我
们就需要将基本数据类型数据转化为对象。
2、包装类
包装类均位于java.lang包,包装类和基本数据类型的对应关系:
3、自动装箱(auto_boxing)与自动拆箱(unboxing)
JDK1.5之前需要手动装箱与拆箱,JDK1.5之后支持自动装箱与自动拆箱。
自动装箱
基本数据类型就自动的封装到与它相同类型的包装中,如:
Integer i = 100;
本质上是,编译器编译时为我们添加了:
Integer i = new Integer(100);
自动拆箱
包装类对象自动转换成基本类型数据。如:
int a = new Integer(100);
本质上,编译器编译时为我们添加了:
int a = new Integer(100).intValue();
4、包装类的作用
(1)数据类型的范围
MIN_VALUE、MAX_VALUE
Float和Double中还有正无穷大POSITIVE_INFINITY、负无穷大NEGATIVE_INFINITY,还有
NaN,是Not a Number的缩写。NaN 用于处理计算中出现的错误情况,比如 0.0 除以 0.0 或者求负数的平方根。
程序员可以利用这种定制的 NaN 值中的特定位模式来表达某些诊断信息。
(2)数据类型的转换
1、字符串转成包装类对象:
(1)使用包装类型的构造方法
除了Character类型,其他7中类型都有1个构造方法,其参数是字符串类型
例如:
Integer t2=new Integer("500");//参数是字符串,字符串的值是必须对应的数值
Integer t3=new Integer("abc");// java.lang.NumberFormatException: For input string: "abc"
(2)使用包装类的valueOf方法
例如:Integer i=Integer.valueOf("500");
2、字符串转成基本数据类型
(1)通过包装类的parseXxx(String s)静态方法
例如:int i=Integer.parseInt("500");
(3)包装类的其他方法
1、Integer类型
public static String toBinaryString(int i) //把十进制转成二进制
public static String toHexString(int i) //把十进制转成十六进制
public static String toOctalString(int i) //把十进制转成八进制
2、Character类型
public static char toUpperCase(char ch) //转成大写字母
public static char toLowerCase(char ch) //转成小写字母
其他的查看相关API文档即可
3、equals
按照包装的基本数据类型的值比较
4、compareTo
按照包装的基本数据类型的值比较
5、缓存问题
我们在编程时大量需要值在-128到127范围之间的Integer对象。如果只能通过new来创建,需要在堆中开辟大量值一样的Integer对象。
这是相当不划算的,IntegerCache.cache很好的起到了缓存的作用。
缓存
byte Byte -128–127
short Short -128–127
int Integer -128—127
long Long -128—127
float Float 不缓存
double Double 不缓存
char Character 0–127
boolean Boolean TURE,FALSE
字符串String类
字符串String类的概述
String 类代表字符串。Java 程序中的所有字符串字面值(如 "abc" )都作为此类的实例实现。
字符串是常量;它们的值在创建之后不能更改。字符串缓冲区支持可变的字符串。因为 String 对象是不可变的,所以可以共享。例如:
String str = "abc";
等效于:
char data[] = {'a', 'b', 'c'};
String str = new String(data);
Java字符串就是Unicode字符序列,例如串“Java”就是4个Unicode字符J、a、v、a组成的。
Java没有内置的字符串类型,而是在标准Java类库中提供了一个预定义的类String,
每个用双引号括起来的字符串都是String的一个实例。
字符串String类的特点
1、String是个final类
2、String是不可变的字符序列
private意味着外面无法直接获取字符数组、final意味着字符数组的引用不可改变。
但是因为String也没有提供修改value数组某元素值的途径,因此字符串的字符数组内容也不可变了。
String对象的创建
String s1 = new String(); // 本质上 this.value = new char[0];
String s2 = new String(String original); //this.value = original.value;
String s3 = new String(char[] a); //this.value = Arrays.copyOf(value, value.length);
String s4 = new String(char[] a,int startIndex,int count)
.......
可变字符序列:字符串缓冲区
一个类似于 String 的字符串缓冲区,但不能修改。虽然在任意时间点上它都包含某种特定的字符序列,
但通过某些方法调用可以改变该序列的长度和内容。
没有final声明,count记录有效字符的个数。
StringBuilder:线程安全,效率低
StringBuffer:线程不安全,效率高
常用方法:
1、StringBuffer的构造方法
StringBuffer() 初始容量为16的字符串缓冲区
StringBuffer(int size) 构造指定容量的字符串缓冲区
StringBuffer(String str) 将内容初始化为指定字符串内容
日期时间类
1、java.lang.System类
System类提供的public static long currentTimeMillis()用来返回当前时间与
1970年1月1日0时0分0秒GMT之间以毫秒为单位的时间差。此方法适于计算时间差。
2、java.util.Date
它的对象表示一个特定的瞬间,精确到毫秒。
Java中时间的表示说白了也是数字,是从标准纪元1970年1月1日0时0分0秒GMT到某个时刻的毫秒数,类型是long
理解:一维的时间轴,选择1970年1月1日0时0分0秒时间为0刻度,1毫秒一刻度
构造方法:
Date(): 源代码:this(System.currentTimeMillis());
Date(long date)
常用方法:
getTime():返回自 1970 年 1 月 1 日 00:00:00 GMT 以来此 Date 对象表示的毫秒数。
toString():把此 Date 对象转换为以下形式的 String: dow mon dd hh:mm:ss zzz yyyy 其中:
dow 是一周中的某一天 (Sun, Mon, Tue, Wed, Thu, Fri, Sat), zzz是时间标准。
3、java.util.Calendar
API:Calendar 类是一个抽象类,它为特定瞬间与一组诸如 YEAR、MONTH、DAY_OF_MONTH、HOUR 等 日历字段之间
的转换提供了一些方法,并为操作日历字段(例如获得下星期的日期)提供了一些方法。
瞬间可用毫秒值来表示,它是距历元(即格林威治标准时间 1970 年 1 月 1 日的 00:00:00.000,
格里高利历)的偏移量。
//默认语言环境的时间(时区)
Calendar c = new GregorianCalendar();
/*
* java.util.GregorianCalendar[
* time=1480667849712,
* areFieldsSet=true,
* areAllFieldsSet=true,
* lenient=true,
* zone=sun.util.calendar.ZoneInfo[id="Asia/Shanghai",offset=28800000,dstSavings=0,useDaylight=false,transitions=19,lastRule=null],
* firstDayOfWeek=1,
* minimalDaysInFirstWeek=1,
* ERA=1,
* YEAR=2016,
* MONTH=11,
* WEEK_OF_YEAR=49,//本年第49周
* WEEK_OF_MONTH=1,//本月第1周
* DAY_OF_MONTH=2,
* DAY_OF_YEAR=337,//本年第337天
* DAY_OF_WEEK=6,
* DAY_OF_WEEK_IN_MONTH=1,
* AM_PM=1, //下午
* HOUR=4,
* HOUR_OF_DAY=16, //HOUR是12小时制, HOUR_OF_DAY是24小时制
* MINUTE=37,
* SECOND=29,
* MILLISECOND=712,
* ZONE_OFFSET=28800000,
* DST_OFFSET=0]
*/
public static void main(String[] args) {
//默认语言环境的时间(时区)
Calendar c = new GregorianCalendar();
int year=c.get(Calendar.YEAR);
int month=c.get(Calendar.MONTH);
int date=c.get(Calendar.DAY_OF_MONTH);
int hour=c.get(Calendar.HOUR_OF_DAY);
int minute=c.get(Calendar.MINUTE);
int second=c.get(Calendar.SECOND);
int mill=c.get(Calendar.MILLISECOND);
int week=c.get(Calendar.DAY_OF_WEEK);
StringBuffer dateStr=new StringBuffer();
dateStr.append(year).append("年");
dateStr.append(month+1).append("月");
dateStr.append(date).append("日").append(" ");
dateStr.append(hour).append("时");
dateStr.append(minute).append("分");
dateStr.append(second).append("秒");
dateStr.append(mill).append("毫秒").append(" ");
String[] weeks={"日","一","二","","四","五","六"};
dateStr.append("星期").append(weeks[week-1]);
System.out.println(dateStr);
}
c.set(2016, Calendar.DECEMBER, 4, 12, 12, 0);
c.setTime(new Date());
c.add(Calendar.DAY_OF_MONTH, 2);//c.add(Calendar.DAY_OF_MONTH, -2);
c.add(Calendar.HOUR, 12);
4、java.text.DateFormat和SimpleDateFormat
完成字符串和时间对象的转化:
format
parse
public static void main(String[] args) {
Date date = new Date();
SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss 是本年的第几D");
System.out.println(sf.format(date));
String s = "2016-12-01 14:12:23";
SimpleDateFormat sf2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
try {
Date d = sf2.parse(s);
System.out.println(d);
} catch (ParseException e) {
e.printStackTrace();
}
}
数学类Math
java.lang.Math提供了一系列静态方法用于科学计算;其方法的参数和返回值类型一般为double型。
abs 绝对值
acos,asin,atan,cos,sin,tan 三角函数
sqrt 平方根
pow(double a,doble b) a的b次幂
log 自然对数
exp e为底指数
max(double a,double b)
min(double a,double b)
random() 返回0.0到1.0的随机数
long round(double a) double型数据a转换为long型(四舍五入)
toDegrees(double angrad) 弧度—>角度
toRadians(double angdeg) 角度—>弧度
比较器:自然排序与定制排序:
java.lang.Comparable
此接口强行对实现它的每个类的对象进行整体排序。这种排序被称为类的自然排序,类的 compareTo 方法被称为它的自然比较方法。
实现此接口的对象列表(和数组)可以通过 Collections.sort(和 Arrays.sort)进行自动排序。实现此接口的对象可以
用作有序映射中的键或有序集合中的元素,无需指定比较器。
对于类 C 的每一个 e1 和 e2 来说,当且仅当 e1.compareTo(e2) == 0 与 e1.equals(e2) 具有相同的 boolean 值时,
类 C 的自然排序才叫做与 equals 一致。注意,null 不是任何类的实例,即使
e.equals(null) 返回 false,e.compareTo(null) 也将抛出 NullPointerException。
建议(虽然不是必需的)最好使自然排序与 equals 一致。这是因为在使用自然排序与 equals 不一致的元素(或键)时,
没有显式比较器的有序集合(和有序映射表)行为表现“怪异”。尤其是,这样的有序集合(
或有序映射表)违背了根据 equals 方法定义的集合(或映射表)的常规协定。
实际上,所有实现 Comparable 的 Java 核心类都具有与 equals 一致的自然排序。
java.math.BigDecimal 是个例外,它的自然排序将值相等但精确度不同的 BigDecimal 对象(比如 4.0 和 4.00)视为相等。
java.util.Compartor
强行对某个对象 collection 进行整体排序 的比较函数。可以将 Comparator 传递给 sort 方法(如 Collections.sort
或 Arrays.sort),从而允许在排序顺序上实现精确控制。
还可以使用 Comparator 来控制某些数据结构(如有序 set或有序映射)的顺序,或者为那些没有自然
顺序的对象 collection 提供排序。
当且仅当对于一组元素 S 中的每个 e1 和 e2 而言,c.compare(e1, e2)==0 与 e1.equals(e2)
具有相等的布尔值时,Comparator c 强行对 S 进行的排序才叫做与 equals 一致 的排序。
当使用具有与 equals 不一致的强行排序能力的 Comparator 对有序 set(或有序映射)进行排序时,
应该小心谨慎。假定一个带显式 Comparator c 的有序 set(或有序映射)与从 set S 中抽取出来的
元素(或键)一起使用。如果 c 强行对 S 进行的排序是与 equals 不一致的,那么有序
set(或有序映射)将是行为“怪异的”。尤其是有序 set(或有序映射)将违背根据 equals 所定义的
set(或映射)的常规协定。
注:通常来说,让 Comparator 也实现 java.io.Serializable 是一个好主意,因为它们在可序列化的
数据结构(像 TreeSet、TreeMap)中可用作排序方法。为了成功地序列化数据结构,Comparator
(如果已提供)必须实现 Serializable。