什么是API?
API(Application Programming interface) 应用程序编程接口。
简单来说:就是Java帮我们已经写好的一些方法,我们直接拿过来用就可以了。
Object
Object类的方法是一切子类对象都可以直接使用的,所以我们要学习Object类的方法。
一个类要么默认继承了Object类,要么间接继承了Object类,Object类是Java中的祖宗类。
toString方法
默认返回:类的全限名@随机数。
toString()方法存在的意义就是为了被子类重写,以便返回对象的内容信息。
equals方法
默认是比较当前对象与另一个对象的地址是否相同,相同返回true,不同返回false。
equals方法存在的意义就是为了被子类重写,以便子类自己来定制比较规则,通常是比较2个子类对象的内容是否相同。
Objects
public static boolean equals(Object a, Object b) 比较两个对象的,底层会先进行非空判断,从而可以避免空指针异常,再进行equals比较。
public static boolean isNull(Object obj) 判断变量是否为null ,为null返回true ,反之为false。
StringBuilder
介绍
StringBuilder是一个可变的字符串类,我们可以把它看成是一个对象容器。
作用:提高字符串的操作效率,如拼接、修改等。
构造器和常用方法
public StringBuilder() 创建一个空白的可变的字符串对象,不包含任何内容。
public StringBuilder(String str)创建一个指定字符串内容的可变字符串对象。
public StringBuilder append(任意类型)添加数据并返回StringBuilder对象本身。
public StringBuilder reverse()将对象的内容反转。
public int length()返回对象内容长度。
public String toString()通过toString()就可以把StringBuilder转换为String。
String类拼接字符串原理图
StringBuilder提高效率原理图
为什么拼接、反转字符串建议使用StringBuilder?
String :内容是不可变的、拼接字符串性能差。
StringBuilder:内容是可变的、拼接字符串性能好、代码优雅。
String和StringBuilder使用场景
通常定义字符串使用String ,拼接、修改等操作字符串使用StringBuilder 。
案例:打印整型数组内容
需求: 设计一个方法用于输出任意整型数组的内容,要求输出成如下格式: “该数组内容为:[11, 22, 33, 44, 55]”
分析:
1、定义一个方法,要求该方法能够接收数组,并输出数组内容。 ---> 需要参数吗?需要返回值类型申明吗?
2、定义一个静态初始化的数组,调用该方法,并传入该数组。
代码:
public class StringBuilderTest2 {
public static void main(String[] args) {
int[] arr1 = null;
System.out.println(toString(arr1));
int[] arr2 = {10, 88, 99};
System.out.println(toString(arr2));
int[] arr3 = {};
System.out.println(toString(arr3));
}
/**
1、定义方法接收任意整型数组,返回数组内容格式
*/
public static String toString(int[] arr){
if(arr != null){
// 2、开始拼接内容。
StringBuilder sb = new StringBuilder("[");
for (int i = 0; i < arr.length; i++) {
sb.append(arr[i] ).append(i == arr.length - 1 ? "" : ", ");
}
sb.append("]");
return sb.toString();
}else {
return null;
}
}
}
Math
包含执行基本数字运算的方法,Math类没有提供公开的构造器。
通过类名就可以直接调用类的成员。
public static int abs(int a)获取参数绝对值。
public static double ceil(double a)向上取整。
public static double floor(double a)向下取整。
public static int round(float a)四舍五入。
public static int max(int a,int b)获取两个int值中的较大值。
public static double pow(double a,double b)返回a的b次幂的值。
public static double random()返回值为double的随机值,范围[0.0,1.0)。
System
System也是一个工具类,代表了当前系统,提供了一些与系统相关的方法。
public static void exit(int status)终止当前运行的 Java 虚拟机(慎用),非零表示异常终止。
public static long currentTimeMillis()返回当前系统的时间毫秒值形式,用于计算程序运行时间。
public static void arraycopy(数据源数组, 起始索引, 目的地数组, 起始索引, 拷贝个数)数组拷贝。
时间毫秒值
计算机认为时间是有起点的,起始时间: 1970年1月1日 00:00:00
时间毫秒值:指的是从1970年1月1日 00:00:00走到此刻的总的毫秒数,应该是很大的。 1s = 1000ms。
原因:
1969年8月,贝尔实验室的程序员肯汤普逊利用妻儿离开一个月的机会,开始着手创造一个全新的革命性的操作系统,他使用B编译语言在老旧的PDP-7机器上开发出了Unix的一个版本。 随后,汤普逊和同事丹尼斯里奇改进了B语言,开发出了C语言,重写了UNIX。1970年1月1日 算C语言的生日。
BigDecimal
用于解决浮点型运算精度失真的问题。
创建对象BigDecimal封装浮点型数据(最好的方式是调用方法)。
public static BigDecimal valueOf(double val): 包装浮点数成为BigDecimal对象。
public BigDecimal add(BigDecimal b)
public BigDecimal subtract(BigDecimal b)
public BigDecimal multiply(BigDecimal b)
public BigDecimal divide(BigDecimal b) 一定要进行精度运算的
public BigDecimal divide (另一个BigDecimal对象,精确几位,舍入模式) 适合除不尽的情况
舍入模式
BigDecimal.ROUND_UP 进一法
BigDecimal.ROUND_FLOOR 去尾法
BigDecimal.ROUND_HALF_UP 四舍五入
日期与时间
Date
Date类代表当前所在系统的日期时间信息。
获取当前时间
public Date() 创建一个Date对象,代表的是系统当前此刻日期时间。
System.currentTimeMillis();
返回时间毫秒值,毫秒值用于时间运算
public long getTime() 返回从1970年1月1日 00:00:00走到此刻的总的毫秒数。
时间毫秒值转换成日期对象:
public Date(long time) 把时间毫秒值转换成Date日期对象。
public void setTime(long time) 设置日期对象的时间为当前时间毫秒值对应的时间。
案例:
其中有计算出当前时间往后走1小时121秒之后的时间是多少。
public class DateDemo1 {
public static void main(String[] args) {
// 1、创建一个Date类的对象:代表系统此刻日期时间对象
Date d = new Date();
System.out.println(d);
// 2、获取时间毫秒值
long time = d.getTime();
System.out.println(time);
// long time1 = System.currentTimeMillis();
// System.out.println(time1);
System.out.println("----------------------------");
// 1、得到当前时间
Date d1 = new Date();
System.out.println(d1);
// 2、当前时间往后走 1小时 121s
long time2 = System.currentTimeMillis();
time2 += (60 * 60 + 121) * 1000;
// 3、把时间毫秒值转换成对应的日期对象。
// Date d2 = new Date(time2);
// System.out.println(d2);
Date d3 = new Date();
d3.setTime(time2);
System.out.println(d3);
}
}
SimpleDateFormat
可以去完成日期时间的格式化操作。
使用步骤:
1、使用指定的格式,构造一个SimpleDateFormat对象:public SimpleDateFormat(String pattern)
2、调用格式化方法
public final String format(Date date) 将日期格式化成日期/时间字符串
public final String format(Object time) 将时间毫秒值式化成日期/时间字符串
格式化的时间形式的常用的模式对应关系如下:
y 年 M 月 d 日 H 时 m 分 s 秒
示例
public class SimpleDateFormatDemo01 {
public static void main(String[] args) {
// 1、日期对象
Date d = new Date();
System.out.println(d);
// 2、格式化这个日期对象 (指定最终格式化的形式)
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss EEE a");
// 3、开始格式化日期对象成为喜欢的字符串形式
String rs = sdf.format(d);
System.out.println(rs);
System.out.println("----------------------------");
// 4、格式化时间毫秒值
// 需求:请问121秒后的时间是多少
long time1 = System.currentTimeMillis() + 121 * 1000;
String rs2 = sdf.format(time1);
System.out.println(rs2);
System.out.println("------------解析字符串时间,下个代码---------------");
}
}
SimpleDateFormat解析字符串时间成为日期对象
public Date parse(String source)
计算出 2021年08月06日11点11分11秒,往后走2天14小时49分06秒后的时间是多少,代码如下:
public class SimpleDateFormatDemo2 {
public static void main(String[] args) throws ParseException {
// 目标: 学会使用SimpleDateFormat解析字符串时间成为日期对象。
// 有一个时间 2021年08月06日 11:11:11 往后 2天 14小时 49分 06秒后的时间是多少。
// 1、把字符串时间拿到程序中来
String dateStr = "2021年08月06日 11:11:11";
// 2、把字符串时间解析成日期对象(本节的重点):形式必须与被解析时间的形式完全一样,否则运行时解析报错!
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
Date d = sdf.parse(dateStr);
// 3、往后走2天 14小时 49分 06秒
long time = d.getTime() + (2L*24*60*60 + 14*60*60 + 49*60 + 6) * 1000;
// 4、格式化这个时间毫秒值就是结果
System.out.println(sdf.format(time));
}
}
案例:秒杀活动
需求
某购物网站举办秒杀活动,开始时间和结束时间如下图所示,
当前活动结束后,系统记录到2位用户的付款时间分别如下:
小贾下单并付款的时间为:2020年11月11日 0:03:47
小皮下单并付款的时间为:2020年11月11日 0:10:11
规则:顾客的付款时间必须在秒杀时间之内,请判断出两位顾客是否秒杀成功。
分析
把4个字符串形式的时间解析成日期对象。
判断小贾和小皮的时间是否在秒杀时间范围之内,并给出相应的提示。
代码实现
public class SimpleDateFormatTest3 {
public static void main(String[] args) throws ParseException {
// 1、开始 和 结束时间
String startTime = "2021-11-11 00:00:00";
String endTime = "2021-11-11 00:10:00";
// 2、小贾 小皮
String xiaoJia = "2021-11-11 00:03:47";
String xiaoPi = "2021-11-11 00:10:11";
// 3、解析他们的时间
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date d1 = sdf.parse(startTime);
Date d2 = sdf.parse(endTime);
Date d3 = sdf.parse(xiaoJia);
Date d4 = sdf.parse(xiaoPi);
if(d3.after(d1) && d3.before(d2)){
System.out.println("小贾秒杀成功,可以发货了!");
}else {
System.out.println("小贾秒杀失败!");
}
if(d4.after(d1) && d4.before(d2)){
System.out.println("小皮秒杀成功,可以发货了!");
}else {
System.out.println("小皮秒杀失败!");
}
}
}
Calendar
概述
Calendar代表了系统此刻日期对应的日历对象。
Calendar是一个抽象类,不能直接创建对象。
Calendar日历类创建日历对象的方法:
public static Calendar getInstance() 获取当前日历对象
Calendar常用方法
注意:calendar是可变日期对象,一旦修改后其对象本身表示的时间将产生变化。
示例
public class CalendarDemo{
public static void main(String[] args) {
// 1、拿到系统此刻日历对象
Calendar cal = Calendar.getInstance();
System.out.println(cal);
// 2、获取日历的信息:public int get(int field):取日期中的某个字段信息。
int year = cal.get(Calendar.YEAR);
System.out.println(year);
int mm = cal.get(Calendar.MONTH) + 1;
System.out.println(mm);
int days = cal.get(Calendar.DAY_OF_YEAR) ;
System.out.println(days);
// 3、public void set(int field,int value):修改日历的某个字段信息。
// cal.set(Calendar.HOUR , 12);
// System.out.println(cal);
// 4.public void add(int field,int amount):为某个字段增加/减少指定的值
// 请问64天后是什么时间
cal.add(Calendar.DAY_OF_YEAR , 64);
cal.add(Calendar.MINUTE , 59);
// 5.public final Date getTime(): 拿到此刻日期对象。
Date d = cal.getTime();
System.out.println(d);
// 6.public long getTimeInMillis(): 拿到此刻时间毫秒值
long time = cal.getTimeInMillis();
System.out.println(time);
}
}
JDK8新增日期类
概述
从Java 8开始,java.time包提供了新的日期和时间API,主要涉及的类型有:
LocalDate:不包含具体时间的日期。
LocalTime:不含日期的时间。
LocalDateTime:包含了日期及时间。
Instant:代表的是时间戳。
DateTimeFormatter 用于做时间的格式化和解析的
Duration:用于计算两个“时间”间隔
Period:用于计算两个“日期”间隔
新API的类型几乎全部是不变类型(和String的使用类似),可以放心使用不必担心被修改。
LocalTime /LocalDate / LocalDateTime
概述
他们分别表示日期,时间,日期时间对象,他们的类的实例是不可变的对象。
他们三者构建对象和API都是通用的。
构建对象的方式如下:
LocalDate、LocalTime、LocalDateTime获取信息的API
public class Demo01LocalDate {
public static void main(String[] args) {
// 1、获取本地日期对象。
LocalDate nowDate = LocalDate.now();
System.out.println("今天的日期:" + nowDate);//今天的日期:
int year = nowDate.getYear();
System.out.println("year:" + year);
int month = nowDate.getMonthValue();
System.out.println("month:" + month);
int day = nowDate.getDayOfMonth();
System.out.println("day:" + day);
//当年的第几天
int dayOfYear = nowDate.getDayOfYear();
System.out.println("dayOfYear:" + dayOfYear);
//星期
System.out.println(nowDate.getDayOfWeek());
System.out.println(nowDate.getDayOfWeek().getValue());
//月份
System.out.println(nowDate.getMonth());//AUGUST
System.out.println(nowDate.getMonth().getValue());//8
System.out.println("------------------------");
LocalDate bt = LocalDate.of(1991, 11, 11);
System.out.println(bt);//直接传入对应的年月日
System.out.println(LocalDate.of(1991, Month.NOVEMBER, 11));//相对上面只是把月换成了枚举
}
}
public class Demo02LocalTime {
public static void main(String[] args) {
// 1、获取本地时间对象。
LocalTime nowTime = LocalTime.now();
System.out.println("今天的时间:" + nowTime);//今天的时间:
int hour = nowTime.getHour();//时
System.out.println("hour:" + hour);//hour:
int minute = nowTime.getMinute();//分
System.out.println("minute:" + minute);//minute:
int second = nowTime.getSecond();//秒
System.out.println("second:" + second);//second:
int nano = nowTime.getNano();//纳秒
System.out.println("nano:" + nano);//nano:
System.out.println("-----");
System.out.println(LocalTime.of(8, 20));//时分
System.out.println(LocalTime.of(8, 20, 30));//时分秒
System.out.println(LocalTime.of(8, 20, 30, 150));//时分秒纳秒
LocalTime mTime = LocalTime.of(8, 20, 30, 150);
System.out.println("---------------");
System.out.println(LocalDateTime.of(1991, 11, 11, 8, 20));
System.out.println(LocalDateTime.of(1991, Month.NOVEMBER, 11, 8, 20));
System.out.println(LocalDateTime.of(1991, 11, 11, 8, 20, 30));
System.out.println(LocalDateTime.of(1991, Month.NOVEMBER, 11, 8, 20, 30));
System.out.println(LocalDateTime.of(1991, 11, 11, 8, 20, 30, 150));
System.out.println(LocalDateTime.of(1991, Month.NOVEMBER, 11, 8, 20, 30, 150));
}
}
LocalDateTime的转换其他类型对象的API
public class Demo03LocalDateTime {
public static void main(String[] args) {
// 日期 时间
LocalDateTime nowDateTime = LocalDateTime.now();
System.out.println("今天是:" + nowDateTime);//今天是:
System.out.println(nowDateTime.getYear());//年
System.out.println(nowDateTime.getMonthValue());//月
System.out.println(nowDateTime.getDayOfMonth());//日
System.out.println(nowDateTime.getHour());//时
System.out.println(nowDateTime.getMinute());//分
System.out.println(nowDateTime.getSecond());//秒
System.out.println(nowDateTime.getNano());//纳秒
//日:当年的第几天
System.out.println("dayOfYear:" + nowDateTime.getDayOfYear());//dayOfYear:249
//星期
System.out.println(nowDateTime.getDayOfWeek());//THURSDAY
System.out.println(nowDateTime.getDayOfWeek().getValue());//4
//月份
System.out.println(nowDateTime.getMonth());//SEPTEMBER
System.out.println(nowDateTime.getMonth().getValue());//9
LocalDate ld = nowDateTime.toLocalDate();
System.out.println(ld);
LocalTime lt = nowDateTime.toLocalTime();
System.out.println(lt.getHour());
System.out.println(lt.getMinute());
System.out.println(lt.getSecond());
}
}
修改相关的API
LocalDateTime 综合了 LocalDate 和 LocalTime 里面的方法,所以下面只用 LocalDate 和 LocalTime 来举例。
这些方法返回的是一个新的实例引用,因为LocalDateTime 、LocalDate 、LocalTime 都是不可变的。
LocalDate的方法如下,LocalTime类似不再说明
public class Demo04UpdateTime {
public static void main(String[] args) {
LocalTime nowTime = LocalTime.now();
System.out.println(nowTime);//当前时间
System.out.println(nowTime.minusHours(1));//一小时前
System.out.println(nowTime.minusMinutes(1));//一分钟前
System.out.println(nowTime.minusSeconds(1));//一秒前
System.out.println(nowTime.minusNanos(1));//一纳秒前
System.out.println("----------------");
System.out.println(nowTime.plusHours(1));//一小时后
System.out.println(nowTime.plusMinutes(1));//一分钟后
System.out.println(nowTime.plusSeconds(1));//一秒后
System.out.println(nowTime.plusNanos(1));//一纳秒后
System.out.println("------------------");
// 不可变对象,每次修改产生新对象!
System.out.println(nowTime);
System.out.println("---------------");
LocalDate myDate = LocalDate.of(2018, 9, 5);
LocalDate nowDate = LocalDate.now();
System.out.println("今天是2018-09-06吗? " + nowDate.equals(myDate));//今天是2018-09-06吗? false
System.out.println(myDate + "是否在" + nowDate + "之前? " + myDate.isBefore(nowDate));//2018-09-05是否在2018-09-06之前? true
System.out.println(myDate + "是否在" + nowDate + "之后? " + myDate.isAfter(nowDate));//2018-09-05是否在2018-09-06之后? false
System.out.println("---------------------------");
// 判断今天是否是你的生日
LocalDate birDate = LocalDate.of(1996, 8, 5);
LocalDate nowDate1 = LocalDate.now();
MonthDay birMd = MonthDay.of(birDate.getMonthValue(), birDate.getDayOfMonth());
MonthDay nowMd = MonthDay.from(nowDate1);
System.out.println("今天是你的生日吗? " + birMd.equals(nowMd));//今天是你的生日吗? false
}
}
Instant时间戳
JDK8获取时间戳特别简单,且功能更丰富。Instant类由一个静态的工厂方法now()可以返回当前时间戳。
时间戳是包含日期和时间的,与java.util.Date很类似,事实上Instant就是类似JDK8 以前的Date。
Instant和Date这两个类可以进行转换。
public class Demo05Instant {
public static void main(String[] args) {
// 1、得到一个Instant时间戳对象
Instant instant = Instant.now();
System.out.println(instant);
// 2、系统此刻的时间戳怎么办?
Instant instant1 = Instant.now();
System.out.println(instant1.atZone(ZoneId.systemDefault()));
// 3、如何去返回Date对象
Date date = Date.from(instant);
System.out.println(date);
Instant i2 = date.toInstant();
System.out.println(i2);
}
}
DateTimeFormatter
在JDK8中,引入了一个全新的日期与时间格式器DateTimeFormatter。
正反都能调用format方法。
public class Demo06DateTimeFormat {
public static void main(String[] args) {
// 本地此刻 日期时间 对象
LocalDateTime ldt = LocalDateTime.now();
System.out.println(ldt);
// 解析/格式化器
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss EEE a");
// 正向格式化
System.out.println(dtf.format(ldt));
// 逆向格式化
System.out.println(ldt.format(dtf));
// 解析字符串时间
DateTimeFormatter dtf1 = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
// 解析当前字符串时间成为本地日期时间对象
LocalDateTime ldt1 = LocalDateTime.parse("2019-11-11 11:11:11" , dtf1);
System.out.println(ldt1);
System.out.println(ldt1.getDayOfYear());
}
}
Duration
在Java8中,我们可以使用以下类来计算时间间隔:java.time.Duration
提供了使用基于时间的值测量时间量的方法。
用于 LocalDateTime 之间的比较。
也可用于 Instant 之间的比较。
public class Demo08Duration {
public static void main(String[] args) {
// 本地日期时间对象。
LocalDateTime today = LocalDateTime.now();
System.out.println(today);
// 出生的日期时间对象
LocalDateTime birthDate = LocalDateTime.of(2021,8
,06,01,00,00);
System.out.println(birthDate);
Duration duration = Duration.between( today , birthDate);//第二个参数减第一个参数
System.out.println(duration.toDays());//两个时间差的天数
System.out.println(duration.toHours());//两个时间差的小时数
System.out.println(duration.toMinutes());//两个时间差的分钟数
System.out.println(duration.toMillis());//两个时间差的毫秒数
System.out.println(duration.toNanos());//两个时间差的纳秒数
}
}
Period
在Java8中,我们可以使用以下类来计算日期间隔:java.time.Period
主要是 Period 类方法 getYears(),getMonths() 和 getDays() 来计算,只能精确到年月日。
用于 LocalDate 之间的比较。
public class Demo07Period {
public static void main(String[] args) {
// 当前本地 年月日
LocalDate today = LocalDate.now();
System.out.println(today);//
// 生日的 年月日
LocalDate birthDate = LocalDate.of(1998, 10, 13);
System.out.println(birthDate);
Period period = Period.between(birthDate, today);//第二个参数减第一个参数
System.out.println(period.getYears());
System.out.println(period.getMonths());
System.out.println(period.getDays());
}
}
ChronoUnit
ChronoUnit类可用于在单个时间单位内测量一段时间,这个工具类是最全的了,可以用于比较所有的时间单位。
public class Demo09ChronoUnit {
public static void main(String[] args) {
// 本地日期时间对象:此刻的
LocalDateTime today = LocalDateTime.now();
System.out.println(today);
// 生日时间
LocalDateTime birthDate = LocalDateTime.of(1990,10,1,
10,50,59);
System.out.println(birthDate);
System.out.println("相差的年数:" + ChronoUnit.YEARS.between(birthDate, today));
System.out.println("相差的月数:" + ChronoUnit.MONTHS.between(birthDate, today));
System.out.println("相差的周数:" + ChronoUnit.WEEKS.between(birthDate, today));
System.out.println("相差的天数:" + ChronoUnit.DAYS.between(birthDate, today));
System.out.println("相差的时数:" + ChronoUnit.HOURS.between(birthDate, today));
System.out.println("相差的分数:" + ChronoUnit.MINUTES.between(birthDate, today));
System.out.println("相差的秒数:" + ChronoUnit.SECONDS.between(birthDate, today));
System.out.println("相差的毫秒数:" + ChronoUnit.MILLIS.between(birthDate, today));
System.out.println("相差的微秒数:" + ChronoUnit.MICROS.between(birthDate, today));
System.out.println("相差的纳秒数:" + ChronoUnit.NANOS.between(birthDate, today));
System.out.println("相差的半天数:" + ChronoUnit.HALF_DAYS.between(birthDate, today));
System.out.println("相差的十年数:" + ChronoUnit.DECADES.between(birthDate, today));
System.out.println("相差的世纪(百年)数:" + ChronoUnit.CENTURIES.between(birthDate, today));
System.out.println("相差的千年数:" + ChronoUnit.MILLENNIA.between(birthDate, today));
System.out.println("相差的纪元数:" + ChronoUnit.ERAS.between(birthDate, today));
}
}
包装类
其实就是8种基本数据类型对应的引用类型。基本数据类型是符号类型。
自动装箱:基本类型的数据和变量可以直接赋值给包装类型的变量。
自动拆箱:包装类型的变量可以直接赋值给基本数据类型的变量。
为什么提供包装类?
Java为了实现一切皆对象,为8种基本类型提供了对应的引用类型。
后面的集合和泛型其实也只能支持包装类型,不支持基本数据类型。
包装类的特有功能
包装类的变量的默认值可以是null,容错率更高。
可以把基本类型的数据转换成字符串类型(用处不大)。
调用toString()方法得到字符串结果。
调用Integer.toString(基本类型的数据)。
可以把字符串类型的数值转换成真实的数据类型(真的很有用)
Integer.parseInt(“字符串类型的整数”)
Double.parseDouble(“字符串类型的小数”)。
示例
public class Test {
public static void main(String[] args) {
int a = 10;
Integer a1 = 11;
Integer a2 = a; // 自动装箱
System.out.println(a);
System.out.println(a1);
Integer it = 100;
int it1 = it; // 自动拆箱
System.out.println(it1);
double db = 99.5;
Double db2 = db; // 自动装箱了
double db3 = db2; // 自动拆箱
System.out.println(db3);
// int age = null; // 报错了!
Integer age1 = null;
Integer age2 = 0;
System.out.println("-----------------");
// 1、包装类可以把基本类型的数据转换成字符串形式。(没啥用)
Integer i3 = 23;
String rs = i3.toString();
System.out.println(rs + 1);
String rs1 = Integer.toString(i3);
System.out.println(rs1 + 1);
// 可以直接+字符串得到字符串类型
String rs2 = i3 + "";
System.out.println(rs2 + 1);
System.out.println("-----------------");
String number = "23";
//转换成整数
// int age = Integer.parseInt(number);
int age = Integer.valueOf(number);
System.out.println(age + 1);
String number1 = "99.9";
//转换成小数
// double score = Double.parseDouble(number1);
double score = Double.valueOf(number1);
System.out.println(score + 0.1);
}
}
正则表达式
概述
正则表达式可以用一些规定的字符来制定规则,并用来校验数据格式的合法性。
初体验
需求:假如现在要求校验一个qq号码是否正确,6位及20位之内,必须全部是数字 。
先使用目前所学知识完成校验需求;然后体验一下正则表达式检验。
public class RegexDemo1 {
public static void main(String[] args) {
// 需求:校验qq号码,必须全部数字 6 - 20位
System.out.println(checkQQ("251425998"));
System.out.println(checkQQ("2514259a98"));
System.out.println(checkQQ(null));
System.out.println(checkQQ("2344"));
System.out.println("-------------------------");
// 正则表达式的初体验:
System.out.println(checkQQ2("251425998"));
System.out.println(checkQQ2("2514259a98"));
System.out.println(checkQQ2(null));
System.out.println(checkQQ2("2344"));
}
public static boolean checkQQ2(String qq){
return qq != null && qq.matches("\\d{6,20}");
}
public static boolean checkQQ(String qq){
// 1、判断qq号码的长度是否满足要求
if(qq == null || qq.length() < 6 || qq.length() > 20 ) {
return false;
}
// 2、判断qq中是否全部是数字,不是返回false
// 251425a87
for (int i = 0; i < qq.length(); i++) {
// 获取每位字符
char ch = qq.charAt(i);
// 判断这个字符是否不是数字,不是数字直接返回false
if(ch < '0' || ch > '9') {
return false;
}
}
return true; // 肯定合法了!
}
}
字符串对象提供了匹配正则表达式的方法
public boolean matches(String regex): 判断是否匹配正则表达式,匹配返回true,不匹配返回false
正则表达式的匹配规则(java.util.regex.Pattern的api文档里有)
字符类(默认匹配一个字符)
[abc] 只能是a, b, 或c
[^abc] 除了a, b, c之外的任何字符
[a-zA-Z] a到z A到Z,包括(范围)
[a-d[m-p]] a到d,或m到p:([a-dm-p]联合)
[a-z&&[def]] d, e, 或f(交集)
[a-z&&[^bc]] a到z,除了b和c:([ad-z]减法)
[a-z&&[^m-p]] a到z,除了m到p:([a-lq-z]减法)
预定义的字符类(默认匹配一个字符)
. 任何字符
\d 一个数字: [0-9]
\D 非数字: [^0-9]
\s 一个空白字符: [ \t\n\x0B\f\r]
\S 非空白字符: [^\s]
\w [a-zA-Z_0-9] 英文、数字、下划线
\W [^\w] 一个非单词字符
贪婪的量词(配合匹配多个字符)
X? X , 一次或根本不
X* X,零次或多次
X+ X , 一次或多次
X {n} X,正好n次
X {n, } X,至少n次
X {n,m} X,至少n但不超过m次
示例
public class RegexDemo02 {
public static void main(String[] args) {
//public boolean matches(String regex):判断是否与正则表达式匹配,匹配返回true
// 只能是 a b c
System.out.println("a".matches("[abc]")); // true
System.out.println("z".matches("[abc]")); // false
// 不能出现a b c
System.out.println("a".matches("[^abc]")); // false
System.out.println("z".matches("[^abc]")); // true
System.out.println("a".matches("\\d")); // false
System.out.println("3".matches("\\d")); // true
System.out.println("333".matches("\\d")); // false
System.out.println("z".matches("\\w")); // true
System.out.println("2".matches("\\w")); // true
System.out.println("21".matches("\\w")); // false
System.out.println("你".matches("\\w")); //false
System.out.println("你".matches("\\W")); // true
System.out.println("---------------------------------");
// 以上正则匹配只能校验单个字符。
// 校验密码
// 必须是数字 字母 下划线 至少 6位
System.out.println("2442fsfsf".matches("\\w{6,}"));
System.out.println("244f".matches("\\w{6,}"));
// 验证码 必须是数字和字符 必须是4位
System.out.println("23dF".matches("[a-zA-Z0-9]{4}"));
System.out.println("23_F".matches("[a-zA-Z0-9]{4}"));
System.out.println("23dF".matches("[\\w&&[^_]]{4}"));
System.out.println("23_F".matches("[\\w&&[^_]]{4}"));
}
}
正则表达式的常见案例
需求
请编写程序模拟用户输入手机号码、验证格式正确,并给出提示,直到格式输入正确为止。
请编写程序模拟用户输入邮箱号码、验证格式正确,并给出提示,直到格式输入正确为止。
请编写程序模拟用户输入电话号码、验证格式正确,并给出提示,直到格式输入正确为止。
分析
定义方法,接收用户输入的数据,使用正则表达式完成检验,并给出提示。
代码
public class RegexTest3 {
public static void main(String[] args) {
// 目标:校验 手机号码 邮箱 电话号码
// checkPhone();
// checkEmail();
// checkTel();
// 同学可以完成校验金额是否格式金额: 99 0.5 99.5 019 | 0.3.3
int[] arr = {10, 4, 5,3, 4,6, 2};
System.out.println(Arrays.binarySearch(arr, 2));
}
public static void checkTel(){
Scanner sc = new Scanner(System.in);
while (true) {
System.out.println("请您输入您的电话号码:");
String tel = sc.next();
// 判断邮箱格式是否正确 027-3572457 0273572457
if(tel.matches("0\\d{2,6}-?\\d{5,20}")){
System.out.println("格式正确,注册完成!");
break;
}else {
System.out.println("格式有误!");
}
}
}
public static void checkEmail(){
Scanner sc = new Scanner(System.in);
while (true) {
System.out.println("请您输入您的注册邮箱:");
String email = sc.next();
// 判断邮箱格式是否正确 3268847878@qq.com
// 判断邮箱格式是否正确 3268847dsda878@163.com
// 判断邮箱格式是否正确 3268847dsda878@pci.com.cn
if(email.matches("\\w{1,30}@[a-zA-Z0-9]{2,20}(\\.[a-zA-Z0-9]{2,20}){1,2}")){
System.out.println("邮箱格式正确,注册完成!");
break;
}else {
System.out.println("格式有误!");
}
}
}
public static void checkPhone(){
Scanner sc = new Scanner(System.in);
while (true) {
System.out.println("请您输入您的注册手机号码:");
String phone = sc.next();
// 判断手机号码的格式是否正确
if(phone.matches("1[3-9]\\d{9}")){
System.out.println("手机号码格式正确,注册完成!");
break;
}else {
System.out.println("格式有误!");
}
}
}
}
正则表达式在字符串方法中的使用
public class RegexDemo04 {
public static void main(String[] args) {
String names = "小路dhdfhdf342蓉儿43fdffdfbjdfaf小何";
String[] arrs = names.split("\\w+");
for (int i = 0; i < arrs.length; i++) {
System.out.println(arrs[i]);
}
String names2 = names.replaceAll("\\w+", " ");
System.out.println(names2);
}
}
正则表达式爬取信息
爬取电话号码和邮箱。
/**
拓展:正则表达式爬取信息中的内容。(了解)
*/
public class RegexDemo05 {
public static void main(String[] args) {
String rs = "来黑马程序学习Java,电话020-43422424,或者联系邮箱" +
"itcast@itcast.cn,电话18762832633,0203232323" +
"邮箱bozai@itcast.cn,400-100-3233 ,4001003232";
// 需求:从上面的内容中爬取出 电话号码和邮箱。
// 1、定义爬取规则,字符串形式
String regex = "(\\w{1,30}@[a-zA-Z0-9]{2,20}(\\.[a-zA-Z0-9]{2,20}){1,2})|(1[3-9]\\d{9})" +
"|(0\\d{2,6}-?\\d{5,20})|(400-?\\d{3,9}-?\\d{3,9})";
// 2、把这个爬取规则编译成匹配对象。
Pattern pattern = Pattern.compile(regex);
// 3、得到一个内容匹配器对象
Matcher matcher = pattern.matcher(rs);
// 4、开始找了
while (matcher.find()) {
String rs1 = matcher.group();
System.out.println(rs1);
}
}
}
Arrays类
概述
数组操作工具类,专门用于操作数组元素的。
常用功能
public class ArraysDemo1 {
public static void main(String[] args) {
// 目标:学会使用Arrays类的常用API ,并理解其原理
int[] arr = {10, 2, 55, 23, 24, 100};
System.out.println(arr);
// 1、返回数组内容的 toString(数组)
// String rs = Arrays.toString(arr);
// System.out.println(rs);
System.out.println(Arrays.toString(arr));
// 2、排序的API(默认自动对数组元素进行升序排序)
Arrays.sort(arr);
System.out.println(Arrays.toString(arr));
// 3、二分搜索技术(前提数组必须排好序才支持,否则出bug)
int index = Arrays.binarySearch(arr, 55);
System.out.println(index);
// 返回不存在元素的规律: - (应该插入的位置索引 + 1)
int index2 = Arrays.binarySearch(arr, 22);
System.out.println(index2);
// 注意:数组如果么有排好序,可能会找不到存在的元素,从而出现bug!!
int[] arr2 = {12, 36, 34, 25 , 13, 24, 234, 100};
System.out.println(Arrays.binarySearch(arr2 , 36));
}
}
Arrays类对于Comparator比较器的支持
Arrays类的排序方法
自定义排序规则
设置Comparator接口对应的比较器对象,来定制比较规则。
如果认为左边数据 大于 右边数据 返回正整数
如果认为左边数据 小于 右边数据 返回负整数
如果认为左边数据 等于 右边数据 返回0
示例
public class Student {
private String name;
private int age;
private double height;
public Student() {
}
public Student(String name, int age, double height) {
this.name = name;
this.age = age;
this.height = height;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public double getHeight() {
return height;
}
public void setHeight(double height) {
this.height = height;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
", height=" + height +
'}';
}
}
public class ArraysDemo2 {
public static void main(String[] args) {
// 目标:自定义数组的排序规则:Comparator比较器对象。
// 1、Arrays的sort方法对于有值特性的数组是默认升序排序
int[] ages = {34, 12, 42, 23};
Arrays.sort(ages);
System.out.println(Arrays.toString(ages));
// 2、需求:降序排序!(自定义比较器对象,只能支持引用类型的排序!!)
Integer[] ages1 = {34, 12, 42, 23};
/**
参数一:被排序的数组 必须是引用类型的元素
参数二:匿名内部类对象,代表了一个比较器对象。
*/
Arrays.sort(ages1, new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
// 指定比较规则。
// if(o1 > o2){
// return 1;
// }else if(o1 < o2){
// return -1;
// }
// return 0;
// return o1 - o2; // 默认升序
return o2 - o1; // 降序
}
});
System.out.println(Arrays.toString(ages1));
System.out.println("-------------------------");
Student[] students = new Student[3];
students[0] = new Student("吴磊",23 , 175.5);
students[1] = new Student("谢鑫",18 , 185.5);
students[2] = new Student("王亮",20 , 195.5);
System.out.println(Arrays.toString(students));
// Arrays.sort(students); // 直接运行奔溃
Arrays.sort(students, new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
// 自己指定比较规则
// return o1.getAge() - o2.getAge(); // 按照年龄升序排序!
// return o2.getAge() - o1.getAge(); // 按照年龄降序排序!!
// return Double.compare(o1.getHeight(), o2.getHeight()); // 比较浮点型可以这样写 升序
return Double.compare(o2.getHeight(), o1.getHeight()); // 比较浮点型可以这样写 降序
}
});
System.out.println(Arrays.toString(students));
}
}