自动装箱和拆箱?autoboxing,unboxing..................................................................... 3
字符串相关类(String、 StringBuffer 、 StringBuilder).................................................... 5
String类的常用方法(已讲过,不再讲!).................................................................. 5
String和StringBuffer和StringBuilder使用要点 //buffer(缓冲器)................................ 7
基本数据类型的包装类
包装类基本知识
JAVA并不是纯面向对象的语言。Java语言是一个面向对象的语言,但是Java中的基本数据类型却是不面向对象的。但是我们在实际使用中经常需要将基本数据转化成对象,便于操作。比如:集合的操作中。例如使用Map对象要操作put()方法时,需要传入的参数是对象而不是基本数据类型。为了解决这个不足,在设计类时为每个基本数据类型设计了一个对应的类进行代表,这样八个和基本数据类型对应的类统称为包装类(Wrapper Class)。
包装类均位于java.lang包,包装类和基本数据类型的对应关系如下表所示:
基本数据类型 | 包装类 |
byte | Byte |
boolean | Boolean |
short | Short |
char | Character |
int | Integer |
long | Long |
float | Float |
double | Double |
在这八个类名中,除了Integer和Character类以后,其它六个类的类名和基本数据类型一直,只是类名的第一个字母大写即可。
包装类的用途
对于包装类说,这些类的用途主要包含两种:
a、作为和基本数据类型对应的类类型存在,方便涉及到对象的操作。
b、包含每种基本数据类型的相关属性如最大值、最小值等,以及相关的操作方法(这些操作方法的作用是在基本类型数据、包装类对象、字符串之间提供转化!)。
所有的包装类(Wrapper Class)都有共同的方法,他们是:
/**
* 测试Integer的用法,其他包装类类似
*/
void testInteger(){
//基本类型转化成Integer对象
Integer int1 = new Integer(10);
Integer int2 = 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();
System.out.println("int能表示的最大整数:"+Integer.MAX_VALUE); //一些常见int类型相关的常量
}
自动装箱和拆箱?autoboxing,unboxing
就是将基本类型和包装类进行自动的互相转换。
JDK5.0后,将自动装箱/拆箱引入java中。
自动装箱的过程:每当需要一种类型的对象时,这种基本类型就自动地封装到与它相同类型的包装中。
自动拆箱的过程:每当需要一个值时,被装箱对象中的值就被自动地提取出来,没必要再去调用intValue()和doubleValue()方法。
自动装箱与拆箱的功能事实上是编译器来帮您的忙,编译器在编译时期依您所编写的语法,决定是否进行装箱或拆箱动作。例如:
Integer i = 100; //装箱过程
相当于编译器自动为您作以下的语法编译:
Integer i = newInteger(100); //拆箱过程
所以自动装箱与拆箱的功能是所谓的“编译器蜜糖”(Compiler Sugar),虽然使用这个功能很方便,但在程序运行阶段您得了解Java的语义。例如下面的程序是可以通过编译的:
Integer i = null;
int j = i;
这样的语法在编译时期是合法的,但是在运行时期会有错误,因为这种写法相当于:
Integer i = null;
int j = i.intValue();
null表示i没有参考至任何的对象实体,它可以合法地指定给对象参考名称。由于实际上i并没有参考至任何的对象,所以也就不可能操作intValue()方法,这样上面的写法在运行时会出现NullPointerException错误。
/**
* 测试自动装箱和拆箱
* 结论:虽然很方便,但是如果不熟悉特殊情况,可能会出错!
*/
static void testBoxing(){
Integer b = 23; //自动装箱
int a = new Integer(20); //自动拆箱
//自动装箱和拆箱,实际上是编译器替我们完成了代码的自动编译,比如:Integer b = 23, 其实运行时执行的仍然是:Integer b = new Integer(23);
//下面的问题我们需要注意:
// Integer c = null;
// int d = c; //此处其实就是:c.intValue(),因此抛空指针异常。
//自动装箱拆箱时,对于-128-127之间的值,编译器仍然会把它当做基本类型处理。
Integer h = 100; Integeru = 100;
Integer h2 = 200; Integeru2 = 200;
if(h==u){
System.out.println("100等于");
}
if(h2==u2){
System.out.println("200等于");
}
}
字符串相关类(String、 StringBuffer 、 StringBuilder)
String类的常用方法(已讲过,不再讲!)
n String 类对象保存不可修改的Unicode字符序列
n String类的下述方法能创建并返回一个新的String对象: concat, replace, substring, toLowerCase, toUpperCase, trim.
n 提供查找功能的有关方法: endsWith, startsWith, indexOf,,lastIndexOf.
n 提供比较功能的方法: equals, equalsIgnoreCase, compareTo.
n 其它方法: charAt ,length.
n public static String valueOf(…)可以将基本类型数据转换为字符串。
StringBuffer和StringBuilder
n StringBuffer和StringBuilder非常类似,均代表可变的字符序列,而且方法也一样。 (StringBuilder被设计用作 StringBuffer的一个简易替换,建议优先采用该类,因为在大多数实现中,它比 StringBuffer 要快。)
n StringBuffer类的常见构造方法:
q StringBuffer()
n 创建一个不包含字符序列的“空”的StringBuffer对象。
q StringBuffer(String str)
n 创建一个StringBuffer对象,包含与String对象str相同的字符序列。-------------------------------------------------------------------------------------------------
n 重载的public StringBuilder append(…)方法 可以为该StringBuilder 对象添加字符序列,返回添加后的该StringBuilder对象引用。
n 方法 public StringBuilder delete(int start,int end) 可以删除从start开始到end-1为止的一段字符序列,返回修改后的该StringBuilder对象引用。
n 方法 public StringBuilder deleteCharAt(int index)移除此序列指定位置上的 char。
n 重载的public StringBuilder insert(…)方法可以为该StringBuilder 对象在指定位置插入字符序列,返回修改后的该StringBuilder对象引用,例如:
publicStringBuilder insert(int offset,String str)
publicStringBuilder insert(int offset,double d)
… ……
n 方法 public StringBuilder setCharAt(int index,char ch)
The character at the specified(详细的、指定的) index is set to ch.
n 和 String 类含义类似的方法:
public intindexOf(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)
n 方法 public StringBuilder reverse()反向的 用于将字符序列逆序,返回修改后的该StringBuilder对象引用。
n 方法 public String toString() 返回此序列中数据的字符串表示形式。
//String/StringBuffer,StringBuilder基本用法和效率测试 String str ="";
Date d = new Date(); for(int i=0;i<10000;i++){ str +=i; }
Date d2 = new Date(); System.out.println(d2.getTime()-d.getTime());
// StringBuilder sb = new StringBuilder(); StringBuffer sb = new StringBuffer(); Date d3 = new Date(); for(int i=0;i<10000;i++){ sb.append(i); }
Date d4 = new Date(); System.out.println(d4.getTime()-d3.getTime()); |
public static void main(String[] args) {
StringBuilder sb = new StringBuilder();
for(int i = 0; i < 7; i++) {
sb.append((char)('a' + i));
}
System.out.println(sb.toString());
sb.append(", I cansing my abc!");
System.out.println(sb.toString());
StringBuffer sb2 = new StringBuffer("中华人民共和国");
sb2.insert(0, "爱").insert(0, "我");
System.out.println(sb2);//我爱中华人民共和国
sb2.delete(0, 2);
System.out.println(sb2);
sb2.deleteCharAt(0).deleteCharAt(0);
System.out.println(sb2.charAt(0));//共
System.out.println(sb2.reverse());//国和共
System.out.println();
}
String和StringBuffer和StringBuilder使用要点
String使用的陷阱:String一经初始化后,就不会在改变其内容了。对String字符串的操作实际上对其副本(原始拷贝)的操作,原来的字符串一点都没有改变。比如:
string s="a"; //创建了一个字符串
s=s+"b"; //实际上原来的"a"字符串对象已经丢弃了,现在又产生了一个字符串s+"b"(也就是"ab")。如果多次执行这些改变串内容的操作,会导致大量副本字符串对象存留在内存中,降低效率。如果这样的操作放到循环中,会极大影响程序的性能。
相反,StringBuffer类是对原字符串本身操作的,可以对字符串进行修改而不产生副本拷贝。可以在循环中使用。
String:不可变字符序列
StringBuffer:可变字符序列,并且线程安全,但是效率低
StringBuilder:可变字符序列,线程不安全,但是效率高(一般用他!)
正则表达式对字符串的处理
(讲完javascript后专门给大家讲!)
时间处理相关类
Date时间类(java.util.Date) util (实用)
在标准Java类库中包含一个Date类。它的对象表示一个特定的瞬间,精确到毫秒。
q Date()分配一个Date对象,并初始化此对象为当前的日期和时间精确到毫秒)。
q Date(long date)分配 Date 对象并初始化此对象,以表示自从标准基准时间(称为“历元(epoch)”,即 1970 年 1 月 1 日 00:00:00 GMT)以来的指定毫秒数。[微软用户1]
q Boolean after(Date when)测试此日期是否在指定日期之后。
q booleanbefore(Date when) 测试此日期是否在指定日期之前。
q Boolean equals(Object obj)比较两个日期的相等性。
q Long getTime()返回自 1970 年 1 月 1 日 00:00:00 GMT 以来此 Date 对象表示的毫秒数。
q String toString()把此 Date 对象转换为以下形式的 String:
dow mon dd hh:mm:ss zzzyyyy 其中: dow 是一周中的某一天 (Sun, Mon, Tue, Wed, Thu, Fri, Sat)。
public static void main(String[] args) {
Datedate1 = new Date();
System.out.println(date1.toString());
long i = date1.getTime();
Datedate2 = new Date(i -1000);
Datedate3 = new Date(i +1000);
System.out.println(date1.after(date2));
System.out.println(date1.before(date2));
System.out.println(date1.equals(date2));
System.out.println(date1.after(date3));
System.out.println(date1.before(date3));
System.out.println(date1.equals(date3));
System.out.println(
new Date(1000L* 60 * 60 * 24 * 365 * 39L[雨林木风2] ).toString()); //why?
}
查看API文档大家可以看到很多方法过时了,JDK1.1之前的Date包含了:日期操作、字符串转化成时间对象,时间对象。 1.1之后,日期操作使用:Canlendar类来。 字符串转化:DateFormat。 (日期格式)
DateFormat类和SimpleDateFormat类
作用:把时间对象转化成指定格式的字符串。反之,把指定格式的字符串转化成时间对象。
DateFormat是一个抽象类。一般使用SimpleDateFormat类。
示例:
public static void main(String[] args) throws 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(s2.format(new Date()));
System.out.println(new SimpleDateFormat("hh:mm:ss").format(new Date()));
//将符合指定格式的字符串转成成时间对象.字符串格式需要和指定格式一致。
String time= "2007-10-7";
Date date = s2.parse(time);
System.out.println("date1:" + date);
time= "2007-10-7 20:15:30";
date = s1.parse(time);
System.out.println("date2:" + date);
}
还可以采用:printf(写格式化输出), string.format方法来格式化时间,大家还记得吗?
格式化字符的含义:
字母 | 日期或时间元素 | 表示 | 示例 |
G | Era 标志符 | AD | |
y | 年 | 1996; 96 | |
M | 年中的月份 | July; Jul; 07 | |
w | 年中的周数 | 27 | |
W | 月份中的周数 | 2 | |
D | 年中的天数 | 189 | |
d | 月份中的天数 | 10 | |
F | 月份中的星期 | 2 | |
E | 星期中的天数 | Tuesday; Tue | |
a | Am/pm 标记 | PM | |
H | 一天中的小时数(0-23) | 0 | |
k | 一天中的小时数(1-24) | 24 | |
K | am/pm 中的小时数(0-11) | 0 | |
h | am/pm 中的小时数(1-12) | 12 | |
m | 小时中的分钟数 | 30 | |
s | 分钟中的秒数 | 55 | |
S | 毫秒数 | 978 | |
z | 时区 | Pacific Standard Time; PST; GMT-08:00 | |
Z | 时区 | -0800 |
Calendar日历类
Calendar 类是一个抽象类,它为特定瞬间与一组诸如 YEAR、MONTH、DAY_OF_MONTH、HOUR 等 日历字段之间的转换提供了一些方法,并为操作日历字段(例如获得下星期的日期)提供了一些方法。瞬间可用毫秒值来表示,它是距历元(即格林威治标准时间 1970 年 1 月 1 日的 00:00:00.000,格里高利历)的偏移量。
GregorianCalendar 是 Calendar 的一个具体子类,提供了世界上大多数国家/地区使用的标准日历系统。
注意月份的表示,一月是0,二月是1,以此类推,是12月是11。因为大多数人习惯于使用单词而不是使用数字来表示月份,这样程序也许更易读,父类Calendar使用常量来表示月份:JANUARY,FEBRUARY,等等。
package chuji;
import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar;
public class AppMain { public static void main(String[] args) { GregorianCalendar calendar = new GregorianCalendar(1999,10,9,22,10,50); GregorianCalendar calendar2 = new GregorianCalendar();
//设置日期 calendar2.set(Calendar.YEAR, 2009); calendar2.set(Calendar.MONTH, Calendar.FEBRUARY); //月份数:0-11 calendar2.set(Calendar.DATE, 3); calendar2.set(Calendar.HOUR_OF_DAY, 10); calendar2.set(Calendar.MINUTE, 20); calendar2.set(Calendar.SECOND, 23);
//得到相关日期元素 int year = calendar.get(Calendar.YEAR); int month = calendar.get(Calendar.MONTH); int day = calendar.get(Calendar.DAY_OF_MONTH); int day2 = calendar.get(Calendar.DATE); //日:Calendar.DATE和Calendar.DAY_OF_MONTH同义 int date = calendar.get(Calendar.DAY_OF_WEEK); //星期几 这里是:1-7.周日是1,周一是2,。。。周六是7 System.out.printf("%d年%d月%d日,星期%d\n",year,month,day,date);
//日期计算 GregorianCalendar calendar3 = new GregorianCalendar(1999,10,9,22,10,50); calendar3.add(Calendar.MONTH, -7); //月份减7 calendar3.add(Calendar.DATE, 7); //增加7天 printCalendar(calendar3);
//日历对象和时间对象转化 Date d = calendar3.getTime(); long millSecond = calendar3.getTimeInMillis();
Date date2 = new Date(); GregorianCalendar calendar4 = new GregorianCalendar(); calendar4.setTime(date2);
long g = System.currentTimeMillis();
}
static void printCalendar(Calendar calendar){ int year = calendar.get(Calendar.YEAR); int month = calendar.get(Calendar.MONTH)+1; int day = calendar.get(Calendar.DAY_OF_MONTH); int day2 = calendar.get(Calendar.DATE); //日:Calendar.DATE和Calendar.DAY_OF_MONTH同义 int date = calendar.get(Calendar.DAY_OF_WEEK)-1; //星期几 String week = ""+((date==0)?"日":date); System.out.printf("%d年%d月%d日,星期%s\n",year,month,day,week); } } |
n 编写程序,利用GregorianCalendar(阳历)类,打印当前月份的日历,样式如下:
今天的日期是 2008-02-23 ,如下为今日所在月份的日历
import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar; import java.util.Scanner;
public class AppMain { public static void main(String[] args) throws ParseException { System.out.println("请输入日期(格式为:2010-3-3):"); Scanner scanner = new Scanner(System.in); String dateString =scanner.nextLine(); //2010-3-1
//将输入的字符串转化成日期类 System.out.println("您刚刚输入的日期是:"+dateString); String[] str = dateString.split("-"); int year = Integer.parseInt(str[0]); int month = new Integer(str[1]); int day = new Integer(str[2]); Calendar c = new GregorianCalendar(year,month-1, day); //Month:0-11 ,1-12
//大家自己补充另一种方式:将字符串通过SImpleDateFormat转化成Date对象,再将Date对象转化成日期类 // SimpleDateFormat sdfDateFormat = new SimpleDateFormat("yyyy-MM-dd"); // Date date = sdfDateFormat.parse(dateString); // Calendar c = new GregorianCalendar(); // c.setTime(date); // int day = c.get(Calendar.DATE);
c.set(Calendar.DATE, 1); int dow = c.get(Calendar.DAY_OF_WEEK); //week:1-7 日一二三四五六 System.out.println("日\t一\t二\t三\t四\t五\t六"); for(int i=0;i<dow-1;i++){ System.out.print("\t"); } int maxDate = c.getActualMaximum(Calendar.DATE); // System.out.println("maxDate:"+maxDate); for(int i=1;i<=maxDate;i++){ StringBuilder sBuilder = new StringBuilder(); if(c.get(Calendar.DATE)==day){ sBuilder.append(c.get(Calendar.DATE)+"*\t"); }else{ sBuilder.append(c.get(Calendar.DATE)+"\t"); } System.out.print(sBuilder); // System.out.print(c.get(Calendar.DATE)+((c.get(Calendar.DATE)==day)?"*":"")+"\t");
if(c.get(Calendar.DAY_OF_WEEK)==Calendar.SATURDAY){ System.out.print("\n"); } c.add(Calendar.DATE, 1); }
}
static void printCalendar(Calendar calendar){ int year = calendar.get(Calendar.YEAR); int month = calendar.get(Calendar.MONTH)+1; int day = calendar.get(Calendar.DAY_OF_MONTH); int day2 = calendar.get(Calendar.DATE); //日:Calendar.DATE和Calendar.DAY_OF_MONTH同义 int date = calendar.get(Calendar.DAY_OF_WEEK)-1; //星期几 String week = ""+( (date==0)?"日":date ); System.out.printf("-----%d年%d月%d日,星期%s\n",year,month,day,week); } } |
Math类
³ java.lang.Math提供了一系列静态方法用于科学计算;其方法的参数和返回值类型一般为double型。
abs 绝对值
acos,asin,atan,cos,sin,tan
sqrt 平方根
pow(double a, double 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) 角度->弧度
File类[t3]
Ø java.io.File类:文件和目录路径名的抽象表示形式。
Ø File类的常见构造方法:
§ public File(String pathname)
以pathname为路径创建File对象,如果pathname是相对路径,则默认的当前路径在系统属性user.dir中存储。
Ø File的静态属性Stringseparator存储了当前系统的路径分隔符。
Ø 通过File对象可以访问文件的属性。
public boolean canRead() public boolean canWrite()
public boolean exists() public boolean isDirectory()
public boolean isFile() public boolean isHidden()
public long lastModified() [修改的] public long length()
public String getName() public String getPath()
Ø 通过File对象创建空文件或目录(在该对象所指的文件或目录不存在的情况下)。
public booleancreateNewFile()throws IOException
public boolean delete()
public boolean mkdir(), mkdirs()[微软用户4]
作业:
编写一个程序,在命令行中以树状结构展现特定的文件夹及其子文件(夹)
package com.cssxt.io;
import java.io.File;
public class FileTree { public static void main(String[] args) { File f = new File("d:/1005班"); printFile(f, 0); }
static void printFile(File file,int level){ for (int i = 0; i < level; i++) { System.out.print("-"); } System.out.println(file.getName());
if(file.isDirectory()){ File[] files = file.listFiles(); for (File temp : files) { printFile(temp, level+1); } } } } |
枚举
³ 枚举类型:
² 只能够取特定值中的一个
² 使用enum关键字
² 所有的枚举类型隐性地继承自 java.lang.Enum。(枚举实质上还是类!而每个被枚举的成员实质就是一个枚举类型的实例,他们默认都是public static final的。可以直接通过枚举类型名直接使用它们。)
² 强烈建议当你需要定义一组常量时,使用枚举类型
² 尽量不要使用枚举的高级特性,事实上高级特性都可以使用普通类来实现,没有必要引入复杂性!
public class TestEnum { public static void main(String[] args) { Week ww = Week.FRIDAY; //定义一个枚举类型对象
Week ww2 = Week.values()[2]; //返回枚举的第三个元素!! System.out.println(ww2);
String temp = testEnum(Week.SUNDAY); System.out.println(temp);
System.out.println(Week.TUESDAY.ordinal()); //返回TUESDAY在枚举中的索引 System.out.println(Week.TUESDAY.toString()); System.out.println(Week.TUESDAY.name()); System.out.println(Week.TUESDAY); }
static String testEnum(Week w){ switch (w) { case SUNDAY: return "日"; case MONDAY: return "一"; case TUESDAY: return "日"; case WEDNESDAY: return "日"; case THURSDAY: return "日"; case FRIDAY: return "日"; case SATURDAY: return "日"; } return ""; }
}
enum Week{ SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY } |
时间的处理本质上是数字的处理!!!
不加L就溢出了。
最好不要像我这样加后面。
放入:IO一章中讲授。
注意两个的区别!!