包装类
java是面向对象语言,但并不是“纯面向对象”的,八大基本数据类型就不是对象。但在实际应用中会经常将基本类型转换成对象,以便操作。为了解决这个不足,设计了和基本对象对应的包装类。
这八个包装类除了Integer和Character,其他都是和基本数据类型一样,但首字母需大写
另外除了Character和Boolean外,其他都属于“数字型”。数字型都属于java.lang.Number的子类。Number是抽象类,因此它的抽象方法它的子类都必须要实现,所以这些数字型包装类都可以相互转换
public class TestWrapper {
public static void main(String[] args) {
Integer i1= new Integer(123);//Integer(int value)
Integer str = new Integer("123");//Integer(String s)
System.out.println("最大值:"+Integer.MAX_VALUE);//最大值:2147483647
System.out.println("最小值:"+Integer.MIN_VALUE);//最小值:-2147483648
System.out.println(Integer.max(1, 2));//2
System.out.println(Integer.min(1, 2));//1
System.out.println(Integer.toBinaryString(10));//1010
System.out.println(Integer.toOctalString(10));//12
}
}
自动装箱拆箱
自动装箱和拆箱就是将基本数据类型和包装类之间进行自动的互相转换。JDK1.5后,Java引入了自动装箱(autoboxing)/拆箱(unboxing)。
Integer i = 100;//自动装箱
int j = new Integer(100); //自动拆箱
- 自动装箱调用的是valueOf()方法,而不是new Integer()方法。
- 自动拆箱调用的xxxValue()方法。
- 包装类在自动装箱时为了提高效率,对于-128~127之间的值会进行缓存处理。超过范围后,对象之间不能再使用==进行数值的比较,而是使用equals方法。
整型、char类型所对应的包装类,在自动装箱时,对于-128~127之间的值会进行缓存处理,其目的是提高效率。
缓存处理的原理为:如果数据在-128~127这个区间,那么在类加载时就已经为该区间的每个数值创建了对象,并将这256个对象 存放到一个名为cache的数组中。每当自动装箱过程发生时(或者手动调用valueOf()时),就会先判断数据是否在该区间,如果在则直接获取数组中对应的包装类对象的引用,如果不在该区间,则会通过new调用包装类的构造方法来创建对象。
public class TestBoxing {
public static void main(String[] args) {
//jdk1.5之前手动完成装箱拆箱
int i = 123;
Integer i1 = new Integer(i);//手工装箱
int i2 = i1.intValue();//手工拆箱
//jdk1.5之后自动完成装箱拆箱
Integer i3 = i;//int-->Integer
int i4 = i3;//Integer-->int
Integer i5 = null ;
//本质上调用i5.intValue()方法,因为i5为空,所以会出现java.lang.NullPointerException异常
int i6 = i5;
}
}
String、StringBuffer、StringBuilder
String是不可变字符序列,因此我们可以将String对象称为“不可变对象”。指的是对象内部的成员变量的值无法再改变。有源码可知:字符串内容全部存储到value[]数组中,而变量value是final类型的,也就是常量(即只能被赋值一次)。 这就是“不可变对象”的典型定义方式。
StringBuffer和StringBuilder非常类似,均代表可变的字符序列。 这两个类都是抽象类AbstractStringBuilder的子类,方法几乎一模一样。StringBuffer和StringBuilder内部也是一个字符数组,但这个字符数组没有用final修饰,随时可以修改。因此,StringBuilder和StringBuffer称之为“可变字符序列”。
区别:
1. StringBuffer JDK1.0版本提供的类,线程安全,做线程同步检查, 效率较低。
2. StringBuilder JDK1.5版本提供的类,线程不安全,不做线程同步检查,因此效率较高。 建议采用该类。
package com.sxt.wrapper;
import java.util.Date;
/**
* StringBuffer和StringBuilder非常类似,均代表可变字符串
* 区别:
* StringBuffer:jdk1.0提供的类,线程安全,做线程同步检查,效率较低
* StringBuilder:jdk1.5提供的类,线程不安全,不做线程同步检查,效率较高 (建议使用)
* 构造方法:
* StringBuffer(String str):构造一个初始化为指定字符串内容的字符缓冲区
* 常用方法:
* append(String str):将字符串追加到StringBuffer的尾部
* length():获取长度
* charAt(int index)返回char在指定索引在这个序列值
* subSequence(int start, int end)返回一个新的字符序列,该序列是该序列的子序列
* substring(int start):返回一个新的String,其中包含此字符序列中当前包含序列的子序列
* indexOf(String str):返回指定字符串第一次出现字符串内的索引
* insert(String str, int fromIndex):在指定下标位置插入内容
* delete(int start, int end):删除此序列的子字符串中的字符
*/
public class TestStringBuffer {
public static void main(String[] args) {
StringBuffer sb = new StringBuffer("hello");
System.out.println(sb.append(",java"));//hello,java
System.out.println("获取指定下标的字符串:"+sb.charAt(0));//h
System.out.println("获取[0,5)的内容:"+sb.substring(0,5));//hello
System.out.println("获取从指定位置到最后的内容:"+sb.substring(5));//,java
System.out.println("java字符串是下标的位置:"+sb.indexOf("a"));//7
System.out.println("插入字符串:"+sb.insert(0, "你好"));//你好hello,java
System.out.println("删除字符串:"+sb.delete(0,2));//hello,java
System.out.println("长度:"+sb.length());//10
Date date = new Date();
System.out.println(System.currentTimeMillis());;
}
}
package com.sxt.wrapper;
/**
* String:不可变字符序列
* StringBuilder,StringBuilder可变字符序列
* 当需要频繁操作字符序列时,需使用StringBuilder,StringBuilder效率更高
*/
public class TestStringBuilder {
public static void main(String[] args) {
StringBuilder sb = new StringBuilder(" ");
long num3 = Runtime.getRuntime().freeMemory();
long time3 = System.currentTimeMillis();
for (int i = 0; i < 50000; i++) {
sb.append(i);
}
long num4 = Runtime.getRuntime().freeMemory();
long time4 = System.currentTimeMillis();
System.out.println("StringBuilder占用内存:"+(num3-num4));//681568
System.out.println("StringBuilder占用时间:"+(time4-time3));//9
}
}
Date时间类(java.util.Date)
1. Date() 分配一个Date对象,并初始化此对象为系统当前的日期和时间,可以精确到毫秒)。
2. Date(long date) 分配 Date 对象并初始化此对象,以表示自从标准基准时间(称为“历元(epoch)”,即 1970 年 1 月 1 日 00:00:00 GMT)以来的指定毫秒数。
3. boolean after(Date when) 测试此日期是否在指定日期之后。
4. booleanbefore(Date when) 测试此日期是否在指定日期之前。
5. boolean equals(Object obj) 比较两个日期的相等性。
6. long getTime() 返回自 1970 年 1 月 1 日 00:00:00 GMT 以来此 Date 对象表示的毫秒数。
7. String toString() 把此 Date 对象转换为以下形式的 String:
dow mon dd hh:mm:ss zzz yyyy 其中: dow 是一周中的某一天 (Sun、 Mon、Tue、Wed、 Thu、 Fri、 Sat)。
package com.sxt.Date;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class TestDate {
public static void main(String[] args) throws ParseException {
Date date = new Date();
System.out.println(date.toString());//Fri Jul 26 09:51:23 CST 2019
System.out.println(date.toLocaleString());//将日期打印为本地语言环境格式显示2019-7-26 9:51:10
Date date2 = new Date(115, 1, 1);//在1900年的基础上叠加,1025-2-1
System.out.println(date2.toLocaleString());//2015-2-1 0:00:00
Date date3 = new Date(3000L);//在1970-1-1
System.out.println(date3.toLocaleString());//1970-1-1 8:00:03
System.out.println("比较日期是否相等:"+date.equals(date2));//false
System.out.println("比较日期是否在指定日期之前:"+date.before(date2));//false
System.out.println("比较日期是否指定日期之后:"+date.after(date2));//true
int year = date.getYear();//获取年份,当前日期距离1900年时间年份差
System.out.println(year);//119
//将日期转为字符串
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日hh时mm分ss");
String str = sdf.format(date);
System.out.println(str);
//将字符串转为日期
String str2 = "2020-2-2";
SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd");
Date dd = sdf2.parse(str2);
System.out.println(dd);
}
}
DateFormat类和SimpleDateFormat类
把时间对象转化成指定格式的字符串。反之,把指定格式的字符串转化成时间对象。
DateFormat是一个抽象类,一般使用它的的子类SimpleDateFormat类来实现。
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class TestDateFormat {
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(daytime);
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);
}
}
Calendar日历类
Calendar 类是一个抽象类,为我们提供了关于日期计算的相关功能,比如:年、月、日、时、分、秒的展示和计算。
GregorianCalendar 是 Calendar 的一个具体子类,提供了世界上大多数国家/地区使用的标准日历系统。注意月份的表示,一月是0,二月是1,以此类推,12月是11。
package com.sxt.calendar;
import java.util.Calendar;
import java.util.GregorianCalendar;
public class TestCalendar {
public static void main(String[] args) {
Calendar ca = new GregorianCalendar(2019,2,3);
System.out.println(ca);
int year = ca.get(Calendar.YEAR);//获取年份
int month = ca.get(Calendar.MONTH);//获取月份0-11
int day = ca.get(Calendar.DATE);//获取日
int hour = ca.get(Calendar.HOUR);//获取时
int minute = ca.get(Calendar.MINUTE);//获取分
int second = ca.get(Calendar.SECOND);//获取秒
System.out.println(year+"-"+(month)+"-"+day+" "+hour+":"+minute+":"+second);
int dayOfWeek = ca.get(Calendar.DAY_OF_WEEK);//获取星期几,(1-7)星期日是第一天
int weekOfMonth = ca.get(Calendar.WEEK_OF_MONTH);//获取一个月的星期几
System.out.println("星期"+dayOfWeek+"第"+weekOfMonth+"周");
Calendar ca2 = new GregorianCalendar();
ca2.set(Calendar.YEAR, 2019);//设置年份
ca2.set(Calendar.MONTH, 2);
ca2.set(Calendar.DATE, 2);
System.out.println(ca2.get(Calendar.YEAR)+" "+ca2.get(Calendar.MONTH));
int day1 = ca2.getMaximum(Calendar.DAY_OF_MONTH);
System.out.println(day1);
}
}
打印日历
public class TestCalendar2 {
public static void main(String[] args) throws ParseException {
System.out.println("请输入日期:yyyy-MM-dd:");
Scanner sc = new Scanner(System.in);
String input = sc.nextLine();
SimpleDateFormat sim = new SimpleDateFormat("yyyy-MM-dd");
Date date = sim.parse(input);//将输入的字符串转换为日期对象
//每月最大日期
Calendar ca = new GregorianCalendar();
ca.setTime(date);//设置日历中的日期为用户输入的日期
//获取当前日期是该月的第几天
int realDate = ca.get(Calendar.DAY_OF_MONTH);
//将日期设置为1号,以便获取本月的第一天是星期几
ca.set(Calendar.DAY_OF_MONTH, 1);//日期本月的1号
int dayOfWeek = ca.get(Calendar.DAY_OF_WEEK);
//打印日期头部
System.out.println("日t一t二t三t四t五t六");
//获取当月日期实际天数
int maxDay = ca.getMaximum(Calendar.DAY_OF_MONTH);
for (int i = 1; i < dayOfWeek; i++) {
System.out.print("t");
}
for (int i = 0; i < maxDay; i++) {
if(i==realDate) {
System.out.print("*");
}
System.out.print(i+"t");
//获取当前是星期几
int day = ca.get(Calendar.DAY_OF_WEEK);
if(day==Calendar.SATURDAY) {//如果是周六则换行
System.out.println();
}
ca.add(Calendar.DAY_OF_MONTH, 1);
}
}
}
Math类
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 的随机数
public class TestMath {
public static void main(String[] args) {
//取整相关操作
System.out.println(Math.ceil(3.2));
System.out.println(Math.floor(3.2));
System.out.println(Math.round(3.2));
System.out.println(Math.round(3.8));
//绝对值、开方、a的b次幂等操作
System.out.println(Math.abs(-45));
System.out.println(Math.sqrt(64));
System.out.println(Math.pow(5, 2));
System.out.println(Math.pow(2, 5));
//Math类中常用的常量
System.out.println(Math.PI);
System.out.println(Math.E);
//随机数
System.out.println(Math.random());// [0,1)
}
}
File类的基本用法
package com.sxt.file;
import java.io.File;
import java.io.IOException;
public class TestFile {
public static void main(String[] args) throws IOException {
File path = new File("E:/YY");
File file = new File(path, "hello.txt");
System.out.println("文件是否存在:"+path.exists());
if(!path.exists()) {
path.mkdirs();
}
System.out.println("是否是目录:"+path.isDirectory());
System.out.println("是否是文件:"+path.isFile());
System.out.println("文件名字:"+file.getName());
File[] fs = path.listFiles();
for(File file3 : fs) {
String fileName = file3.getName();
long fileSize = file3.length();
String filePath = file3.getPath();
System.out.println(fileName+"---"+fileSize+"---"+filePath);
}
}
}
使用递归算法,以树状结构展示目录树
package com.sxt.file;
import java.io.File;
/**
* 打印文件信息:
* -aa
* --aa.txt
* --bb
* ---bb.txt
* -cc
* --cc.txt
* -dd
*/
public class TestFile2 {
public static void main(String[] args) {
File f= new File("E:/mycode");
printFile(f,0);
}
public 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[] listFiles = file.listFiles();
for(File f : listFiles) {
printFile(f,level+1);//递归调用该方法,注意+1
}
}
}
}
枚举
所有的枚举类型隐性地继承自 java.lang.Enum。枚举实质上还是类!而每个被枚举的成员实质就是一个枚举类型的实例,他们默认都是public static final修饰的。可以直接通过枚举类型名使用它们。
package com.sxt.enu;
import java.util.Random;
public class TestEnum {
public static void main(String[] args) {
//枚举遍历
for(Week k : Week.values()) {
System.out.println(k);
}
//switch语句使用枚举
int a = new Random().nextInt(4);
switch (Season.values()[a]) {
case SPRING:
System.out.println("春天");
break;
case SUMMER:
System.out.println("夏天");
break;
case AUTUMN:
System.out.println("秋天");
break;
case WINTER:
System.out.println("冬天");
break;
}
}
enum Season{
SPRING, SUMMER, AUTUMN,WINTER
}
enum Week{
星期一,星期二,星期三,星期四,星期五,星期六,星期日
}
}