第21章-其他
方法可变长参数
概述
- 在方法定义过程中,如果有形式参数个数不确定的业务场景,就可以使用可变长参数
- 在JDK1.5以前,多使用数组来完成可变长参数,如入口方法main方法中的args参数
- 后续JDK版本中,也提供了专门的语法来实现可变长参数,关键字为三个点(...)
- 可变长参数要求
- 一个方法形参中,只能有一个可变长参数
- 可变长参数必须放在所有形式参数最后一个
语法规则
访问修饰符 [其他修饰符] 返回值类型 方法名([参数类型 参数名,参数类型... 参数名]){
//方法体
return 返回值;
}
语法解释:
- ...,注意上面的形式参数中的最后一个形式参数,使用的是参数类型+...,即表示此方法接收可变长参数
应用实例
实例1,可变长参数的几种方式
package com.bjpowernode.demo;
import java.util.Arrays;
/**
* 可变长参数示例
*/
public class VariableLengthDemo {
public static void main(String[] args) {
String[] datas = {"aaa", "bbb", "ccc"};
//可变长参数(数组)
System.out.println("------------可变长参数(数组)------------");
VariableLengthDemo.methodA(1, 2, datas);
//可变长参数(...)方式一
System.out.println("------------可变长参数(...)方式一------------");
VariableLengthDemo.methodB(1, 2, datas);
//可变长参数(...)方式二
System.out.println("------------可变长参数(...)方式二------------");
VariableLengthDemo.methodB(1, 2, "111", "222", "333", "444");
}
/**
* 使用数组做为可变长参数
*
* @param a
* @param b
* @param datas
*/
public static void methodA(int a, int b, String[] datas) {
System.out.println("可变长参数为(数组):" + Arrays.toString(datas));
}
/**
* 可变长参数
*
* @param a
* @param b
* @param datas
*/
public static void methodB(int a, int b, String... datas) {
System.out.println("可变长参数(...):" + Arrays.toString(datas));
}
}
【练习】
- 练习演示的内容,完成代码编写
传值和传引用
概述
- 在实际的应用过程中,经常会涉及到方法调用过程中的参数数据传递
- 参数数据传递,针对基本数据类型、引用数据类型还有一定的差异
传值
问题:下面的代码,在方法调用后,将输出什么内容?
package com.bjpowernode.demo;
/**
* 传值调用
*/
public class ValueDemo {
public static void main(String[] args) {
//定义变量
int first = 5;
int second = 20;
System.out.println("----------调用方法前----------");
System.out.println("first=" + first);
System.out.println("second=" + second);
ValueDemo.swap(first, second);
System.out.println("----------调用方法后----------");
System.out.println("first=" + first);
System.out.println("second=" + second);
}
/**
* 交换;基本数据类型,传递的是值的拷贝
*
* @param first
* @param second
*/
public static void swap(int one, int two) {
//交换
int temp = one;
one = two;
two = temp;
// System.out.println("----------方法内----------");
// System.out.println("one=" + one);
// System.out.println("two=" + two);
}
}
- 上面,就是典型的调用方法时的传值
- 基本数据类型做为方法的形式参数传递数据时,在方法中接收的是值的拷贝,在方法中对形式参数的修改,并不影响实际参数的值,称之为传值
传引用
引用数据类型做为方法的形式参数传递数据时,在方法中接收的是引用本身的地址的拷贝,在方法中对形式参数的修改,称之为传引用,分两种情况:
- 修改引用的值,不影响实际参数的值
- 修改引用的对象的属性,影响实际参数的值
修改引用的值,不影响实际参数的值
问题:下面的代码,在方法调用后,将输出什么内容?
package com.bjpowernode.demo;
/**
* 传引用,修改引用的值
*/
public class ReferenceDemo {
//属性
public int first;
public Integer second;
/**
* 构造方法
* @param first
* @param second
*/
public ReferenceDemo(int first,Integer second){
this.first = first;
this.second = second;
}
public static void main(String[] args) {
//定义两个对象
ReferenceDemo referenceDemo = new ReferenceDemo(5,15);
System.out.println("----------调用方法前----------");
System.out.println("ReferenceDemo.one=" + referenceDemo.first);
System.out.println("ReferenceDemo.two=" + referenceDemo.second);
ReferenceDemo.change(referenceDemo);
System.out.println("----------调用方法后----------");
System.out.println("ReferenceDemo.one=" + referenceDemo.first);
System.out.println("ReferenceDemo.two=" + referenceDemo.second);
}
/**
* 修改引用的值
* @param referenceDemo
*/
public static void change(ReferenceDemo referenceDemo){
//修改引用的值
referenceDemo = new ReferenceDemo(10,30);
}
}
修改引用的对象的属性,影响实际参数的值
问题:下面的代码,在方法调用后,将输出什么内容?
package com.bjpowernode.demo;
/**
* 传引用,修改引用的对象的属性
*/
public class ReferenceDemo {
//属性
public int first;
public Integer second;
/**
* 构造方法
*
* @param first
* @param second
*/
public ReferenceDemo(int first, Integer second) {
this.first = first;
this.second = second;
}
public static void main(String[] args) {
//定义两个对象
ReferenceDemo referenceDemo = new ReferenceDemo(5, 15);
System.out.println("----------调用方法前----------");
System.out.println("ReferenceDemo.one=" + referenceDemo.first);
System.out.println("ReferenceDemo.two=" + referenceDemo.second);
ReferenceDemo.change(referenceDemo);
System.out.println("----------调用方法后----------");
System.out.println("ReferenceDemo.one=" + referenceDemo.first);
System.out.println("ReferenceDemo.two=" + referenceDemo.second);
}
/**
* 修改引用的对象的属性
*
* @param referenceDemo
*/
public static void change(ReferenceDemo referenceDemo) {
//交换
int temp = referenceDemo.first;
referenceDemo.first = referenceDemo.second;
referenceDemo.second = temp;
}
}
【练习】
- 练习演示的内容,完成代码编写
字符串相关
概述
- 由于字符串处理的使用频率非常高,相应的字符串处理的方式与机制也很多
- 除了熟悉String的拼接,String类型的常用方法外,还有很多与String相关的类和方法
格式化输出字符串
经常需要进行字符串拼接,如果直接使用+进行拼接,可能效果并不是实际业务需要的,如下实例
应用实例
应用实例1,使用+拼接字符串,并不符合要求;Employee类的toString方法中,no需要是补全5位,weight保留1位小数,baseSalary保留2位小数
示例代码
package com.bjpowernode.demo;
/**
* 工作人员类
*/
public class Employee {
//编号,一般要求5位输出,如00101
private Integer no;
//姓名
private String name;
//年龄
private Integer age;
//体重,输出时保留1位小数
private Float weight;
//工资,输出时保持2位小数
private Double salary;
public Employee(Integer no, String name, Integer age, Float weight, Double salary) {
this.no = no;
this.name = name;
this.age = age;
this.weight = weight;
this.salary = salary;
}
@Override
public String toString() {
return "[编号:" + this.no + ",姓名:" + this.name + ",年龄:" + this.age + ",体重:" + this.weight + ",工资:" + this.salary + "]";
}
/**
* 入口方法
*
* @param args
*/
public static void main(String[] args) {
//定义对象
Employee employee = new Employee(101, "张三", 34, 250.372f, 18350.2871);
//输出对象信息
System.out.println(employee.toString());
}
}输出结果,编号、体重、工资并不符合要求
引入String.format方法,进行格式化,如下实例
应用实例
应用实例1,使用String.format格式化字符串,将上述的toString方法代码块替换成如下代码块
示例代码
@Override
public String toString() {
return String.format("[编号:%08d,姓名:%s,年龄:%d,体重:%.1f,工资:%.2f]", this.no, this.name, this.age, this.weight, this.salary);
}输出结果,编号、体重、工资符合要求
具体语法如下
String.format格式化语法
【练习】
- 练习演示的内容,完成代码编写
StringBuilder
String的处理中,虽然引入了字符串常量池,能有效提升存储和处理的性能
但,在一些频繁的多个字符串的拼接,会产生很多无用的中间字符串,会对性能有一定的影响;像如下代码
//使用+拼接字符串
String result = "[编号:" + this.no + ",姓名:" + this.name + ",年龄:" + this.age + ",体重:" + this.weight + ",工资:" + this.salary + "]";此时,可使用StringBuilder,能有效的提升字符串拼接的效率;如改成如下代码
//使用Stringuilder拼接字符串
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("[编号:");
stringBuilder.append(this.no );
stringBuilder.append(",姓名:");
stringBuilder.append(this.name);
stringBuilder.append(",年龄:");
stringBuilder.append(this.age);
stringBuilder.append(",体重:");
stringBuilder.append(this.weight);
stringBuilder.append(",体重:");
stringBuilder.append(this.salary);
//StringBuilder转字符串
String result = stringBuilder.toString();特点:
- 效率高
- 更灵活
- 线程不安全
常用方法
- append,追加,可追加字符串、基本数据类型
- insert,插入,可在指定位置插入字符串、基本数据类型
- delete,删除,删除从指定开始位置,到指定结束位置的字符串
- replace,替换,替换从指定开始位置,到指定结束位置的字符串为新的字符串
- indexOf,返回子字符串位置,返回子字符串串在父字符串中的位置
- reverse,反转,将字符串按字符反转返回
- ...
StringBuffer
- 与StringBuilder效果、方法都类似
- 特点:
- 效率高
- 更灵活
- 线程安全
【演示】
时间对比,查看运行效果
使用+拼接
package com.bjpowernode.demo;
import java.util.Date;
/**
* 字符串拼接示例
*/
public class StringConcatDemo {
public static void main(String[] args) {
//开始时间
Date start = new Date();
//使用+拼接
String result = "";
for(int i=0;i<100000;i++){
result = result + "a";
}
//结束时间
Date end = new Date();
//结束时间与开始时间相差毫秒数
long difference=end.getTime()-start.getTime();
//输出
System.out.println("拼接耗时:"+difference+"毫秒");
}
}使用StringBuilder
package com.bjpowernode.demo;
import java.util.Date;
/**
* 字符串拼接示例
*/
public class StringConcatDemo {
public static void main(String[] args) {
//开始时间
Date start = new Date();
//使用+拼接
StringBuilder stringBuilder = new StringBuilder();
for (int i = 0; i < 100000; i++) {
stringBuilder.append("a");
}
//结束时间
Date end = new Date();
//结束时间与开始时间相差毫秒数
long difference = end.getTime() - start.getTime();
//输出
System.out.println("拼接耗时:" + difference + "毫秒");
}
}
【练习】
- 练习应用实例内容,完成代码编写
- 自己学习StringBuilder,对其所有常用方法进行练习
数组相关
概述
- 实际工作中,也经常需要对数组中的数据进行操作和处理
- Java类库中提供了java.util.Arrays类来进行相应处理
Arrays类
常用方法
- toString,将数组转换成字符串
- sort,数组排序
- binarySearch,在一个为升序的有序数组中查找元素,返回其下标
- copyOf,从一个数组拷贝生成新的数组
- ...
应用实例
实例1,常用方法,使用包装类
示例代码
package com.bjpowernode.demo;
import java.util.Arrays;
import java.util.Comparator;
/**
* Arrays类实例
*/
public class ArraysDemo {
public static void main(String[] args) {
//定义数组
Integer[] datas = {33, 77, 44, 99, 88, 22, 66};
//toString方法
System.out.println("-------------toString方法-------------");
System.out.println(Arrays.toString(datas));
System.out.println(datas.toString());
//sort方法
System.out.println("-------------sort方法-------------");
//升序
Arrays.sort(datas);
System.out.println(Arrays.toString(datas));
// //降序
// Arrays.sort(datas, new Comparator <Integer>() {
// @Override
// public int compare(Integer o1, Integer o2) {
// if (o1 < o2) {
// return 1;
// } else {
// return -1;
// }
// }
// });
// System.out.println(Arrays.toString(datas));
//binarySearch方法
System.out.println("-------------binarySearch方法-------------");
System.out.println(Arrays.binarySearch(datas, 99));
//copyOf方法
System.out.println("-------------copyOf方法-------------");
Integer[] newDatas = Arrays.copyOf(datas, 3);
System.out.println(Arrays.toString(newDatas));
}
}实例2,常用方法,使用自定义类型
自定义类型代码
package com.bjpowernode.demo;
/**
* 工作人员类,实现Comparable接口,并覆盖compareTo方法
*/
public class Employee implements Comparable<Employee> {
private Integer no;
//姓名
private String name;
//性别
private Character sex;
//年龄
private Integer age;
public Employee() {
}
public Employee(Integer no, String name, Character sex, Integer age) {
this.no = no;
this.name = name;
this.sex = sex;
this.age = age;
}
/**
* 覆盖compareTo方法,实现两个工作人员比较
* 比较逻辑,使用no比较,当前对象no大于比较对象no,返回1,小于返回-1,相对返回0
* 注意,是否重复,是根据返回是否为0判断
*
* @param o
* @return
*/
@Override
public int compareTo(Employee o) {
if (this.getNo().intValue() > o.getNo().intValue()) {
return 1;
} else if (this.getNo().intValue() < o.getNo().intValue()) {
return -1;
} else {
return 0;
}
}
@Override
public String toString() {
return "Employee{" + "no=" + no + ", name='" + name + '\'' + ", sex=" + sex + ", age=" + age + '}';
}
public Integer getNo() {
return no;
}
public void setNo(Integer no) {
this.no = no;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Character getSex() {
return sex;
}
public void setSex(Character sex) {
this.sex = sex;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}实例代码
package com.bjpowernode.demo;
import java.util.Arrays;
import java.util.Comparator;
/**
* Arrays类实例
*/
public class ArraysDemo {
public static void main(String[] args) {
//定义数组
Employee[] employees = new Employee[3];
Employee employee = new Employee(1001,"张三",'男',44);
employees[0] = employee;
employee = new Employee(1009,"李四",'女',32);
employees[1] = employee;
employee = new Employee(1007,"王五",'男',18);
employees[2] = employee;
//toString方法
System.out.println("-------------toString方法-------------");
System.out.println(Arrays.toString(employees));
System.out.println(employees.toString());
//sort方法
System.out.println("-------------sort方法-------------");
//升序
Arrays.sort(employees);
System.out.println(Arrays.toString(employees));
//binarySearch方法
System.out.println("-------------binarySearch方法-------------");
System.out.println(Arrays.binarySearch(employees, new Employee(1009,null,null,null)));
//copyOf方法
System.out.println("-------------copyOf方法-------------");
Employee[] newDatas = Arrays.copyOf(employees, 2);
System.out.println(Arrays.toString(newDatas));
}
}
【练习】
- 练习演示的内容,完成代码编写
与ArrayList相互转换
概述
- 实际工作中,数组与ArrayList都有着广泛的应用
- 在一些应用场景中,需要将数组与ArrayList进行相互转换
- 除了遍历进行转换,还能使用类的一些方法进行转换
应用实例
实例1,数据与ArrayList相互转换
代码
package com.bjpowernode.demo;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* 数组与ArrayList相互转换
*/
public class ArrayAndListDemo {
public static void main(String[] args) {
//数组转List
System.out.println("--------------数组转List--------------");
String[] arrayDatas = {"aaa", "bbb", "ccc"};
//转换
List <String> listDatas = Arrays.asList(arrayDatas);
//输出
System.out.println(listDatas);
//List转数组
System.out.println("--------------List转数组--------------");
listDatas = new ArrayList <>();
listDatas.add("111");
listDatas.add("222");
listDatas.add("333");
arrayDatas = new String[listDatas.size()];
//转换
listDatas.toArray(arrayDatas);
//输出
System.out.println(Arrays.toString(arrayDatas));
}
}
【练习】
- 练习演示的内容,完成代码编写
日期和时间
概述
- 在实际的业务中,日期/时间的处理,也是常见的,如人员的生日,数据记录时的创建时间、更新时间等
- 随着Java语言的本身发展,出现了多种时间处理的类,主要集中在java.util包和java.time包
- 常用的类有Date、Calendar、Instant等
Date类
比较老的一个日期/时间类
记录从1970年1月1日00:00:00开始的时间
精确到毫秒
常用方法
- 无参构造,定义一个当前操作系统时间的日期/时间对象
- compareTo,比较两个日期的大小,大于返回1,等于返回0,小于返回-1;还有其他类似比较方法,像after、before等方法
- getTime,获取从1970年1月1日00:00:00以来的毫秒数表示,long类型
- toString,返回字符串形式的CST(中国标准时间)
- toInstant,转最新的Instant时间格式,使用UTC(世界标准时间)
应用实例
应用实例1,Date常用方法
实例代码
package com.bjpowernode.demo;
import java.util.Date;
/**
* Date示例
*/
public class DateDemo {
public static void main(String[] args) throws InterruptedException {
//当前时间
Date current = new Date();
System.out.println(current);
//比较时间,compareTo
Date other = new Date();
System.out.println(other.compareTo(current)); //晚定义的时间other大于current,返回1
//获取时间毫秒数,getTime
long milliseconds = current.getTime();
System.out.println(milliseconds);
//toString
System.out.println(current.toString());
//toInstant
System.out.println(current.toInstant());
}
}输出结果,运行查看结果
SimpleDateFormat类,Date格式化类
从上述应用实例的toString可知,输出的时间格式不一 定是我们需要的格式
按需要格式化,就需要SimpleDateFormat类
应用实例
应用实例1,日期格式化
实例代码
package com.bjpowernode.demo;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* Date日期时间格式化示例
*/
public class SimpleDateFormatDemo {
public static void main(String[] args) {
//当前时间
Date current = new Date();
//默认格式,CST(中国标准时间)
System.out.println(current);
//只需要日期
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
System.out.println(simpleDateFormat.format(current));
//只需要时间
simpleDateFormat = new SimpleDateFormat("HH:mm:ss.S");
System.out.println(simpleDateFormat.format(current));
//完整的日期时间
simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.S");
System.out.println(simpleDateFormat.format(current));
//自定义的日期模式字符串转日期对象
simpleDateFormat = new SimpleDateFormat("yyyy年MM月dd日HH小时mm分钟ss秒S毫秒");
String str="2023年2月14日18小时32分钟09秒256毫秒";
Date date = null;
try {
date = simpleDateFormat.parse(str);
} catch (ParseException e) {
e.printStackTrace();
}
System.out.println(date);
}
}输出结果,运行查看结果
常用格式化规则
日期/时间格式化规则(图片来自网络)
【练习】
- 练习演示的内容,完成代码编写
Calendar类【扩展】
日历抽象类,多用于替代Date类中一些过期的方法
能获取日期/时间中的局部数据,如年份、月份等
使用方式与Date基本类似
常用方法
- getInstance,获取Calendar类实例,并且使用当前时间
- get,获取日期/时间的局部,如年份、月份等,借助静态常量实现
- getTime,获取相应的Date对象
- setTime,使用Date对象的时间设置Calendar对象时间
应用实例
应用实例1,Calendar类使用
实例代码
package com.bjpowernode.demo;
import java.util.Calendar;
import java.util.Date;
/**
* Calendar示例
*/
public class CalendarDemo {
public static void main(String[] args) {
//获取当前时间
Calendar calendar = Calendar.getInstance();
//获取日历详情,get
System.out.println(calendar.get(Calendar.YEAR)); //年
System.out.println(calendar.get(Calendar.MONTH)); //月,从0开始,0表示1月
System.out.println(calendar.get(Calendar.DAY_OF_MONTH)); //日
System.out.println(calendar.get(Calendar.HOUR_OF_DAY)); //时
System.out.println(calendar.get(Calendar.MINUTE)); //分
System.out.println(calendar.get(Calendar.SECOND)); //秒
System.out.println(calendar.get(Calendar.MILLISECOND)); //毫秒
//转Date,getTime
Date date = calendar.getTime();
System.out.println(date);
//使用Date设置Calendar时间,setTime
Calendar other = Calendar.getInstance();
other.setTime(date);
System.out.println(calendar.get(Calendar.MILLISECOND));
}
}输出结果,运行查看结果
【练习】
- 练习演示的内容,完成代码编写
LocalDate类、LocalTime类、LocalDateTime类和Instant类【扩展】
Java 8 推出的日期/时间类,位于java.time包中
LocalDate类
不带时区的日期类
常用方法
- now,获取当前日期,静态方法,用于构建LocalDate
- getYear,获取年
- getMonth,获取月,如果需要数值型,也可以用getMonthValue方法
- getDayOfMonth,获取日
应用实例
应用实例1,LocalDate类
实例代码
package com.bjpowernode.demo;
import java.time.LocalDate;
/**
* LocalDate实例
*/
public class LocalDateDemo {
public static void main(String[] args) {
//定义对象
LocalDate localDate = LocalDate.now();
System.out.println(localDate);
//年
System.out.println(localDate.getYear());
//月
System.out.println(localDate.getMonthValue());
//日
System.out.println(localDate.getDayOfMonth());
}
}输出结果,运行查看结果
LocalTime类
不带时区的时间类
常用方法
- now,获取当前时间,静态方法,用于构建LocalTime
- getHour,获取时
- getMinute,获取分
- getSecond,获取秒
- getNano,获取纳秒
应用实例
实例代码
package com.bjpowernode.demo;
import java.time.LocalTime;
/**
* LocalTime实例
*/
public class LocalTimeDemo {
public static void main(String[] args) {
//定义对象
LocalTime localTime = LocalTime.now();
//时
System.out.println(localTime.getHour());
//分
System.out.println(localTime.getMinute());
//秒
System.out.println(localTime.getSecond());
//纳秒
System.out.println(localTime.getNano());
}
}输出结果,运行查看结果
LocalDateTime类
不带时区日期/时间类
常用方法,参见前面的LocalDate类、LocalTime类
应用实例
应用实例1,LocalDateTime类
实例代码
package com.bjpowernode.demo;
import java.time.LocalDateTime;
/**
* LocalDateTime实例
*/
public class LocalDateTimeDemo {
public static void main(String[] args) {
//定义对象
LocalDateTime localDateTime = LocalDateTime.now();
System.out.println(localDateTime);
//年
System.out.println(localDateTime.getYear());
//月
System.out.println(localDateTime.getMonthValue());
//日
System.out.println(localDateTime.getDayOfMonth());
//时
System.out.println(localDateTime.getHour());
//分
System.out.println(localDateTime.getMinute());
//秒
System.out.println(localDateTime.getSecond());
//纳秒
System.out.println(localDateTime.getNano());
}
}输出结果,运行查看结果
Instant类
时间戳类
可以精确到纳秒
描述用0时区的从1970年1月1日00:00:00开始的时间开始的时间戳
常用方法
- now,获取当前时间,静态方法,用于构建Instant
- ofEpochSecond,静态方法,使用秒、纳秒构建Instant
- getEpochSecond,获取时间的秒描述
- toEpochMilli,获取时间的秒+毫秒描述
- getNano,获取纳秒部分
应用实例
应用实例1,Instant类
实例代码
package com.bjpowernode.demo;
import java.time.Instant;
/**
* Instant实例
*/
public class InstantDemo {
public static void main(String[] args) {
//定义对象,now()使用的是System.currentTimeMillis(),只能精确到毫秒,可切换使用
// Instant instant = Instant.now();
Instant instant = Instant.ofEpochSecond(33,44);
//当前时间
System.out.println(instant);
//秒描述
System.out.println(instant.getEpochSecond());
//毫秒描述
System.out.println(instant.toEpochMilli());
//纳秒
System.out.println(instant.getNano());
}
}输出结果,运行查看结果
DateTimeFormatter类,Instant格式化类
应用实例
应用实例1,日期格式化
实例代码
package com.bjpowernode.demo;
import java.time.Instant;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
/**
* DateTimeFormatter示例
*/
public class DateTimeFormatterDemo {
public static void main(String[] args) {
//当前时间
Instant current = Instant.now();
//默认格式,UTC(世界标准时间)
System.out.println(current);
//只需要日期,后面是区域、时区
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd").withLocale(Locale.CHINA).withZone(ZoneId.systemDefault());
System.out.println(dateTimeFormatter.format(current));
//只需要时间
dateTimeFormatter = DateTimeFormatter.ofPattern("HH:mm:ss.SSS").withLocale(Locale.CHINA).withZone(ZoneId.systemDefault());
System.out.println(dateTimeFormatter.format(current));
//完整的日期时间
dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS").withLocale(Locale.CHINA).withZone(ZoneId.systemDefault());
System.out.println(dateTimeFormatter.format(current));
}
}输出结果,运行查看结果
【练习】
- 练习演示的内容,完成代码编写
Math类
数学计算是程序中非常常见的应用,熟悉一些常见的数据计算工具很重要
java.lang.Math类,提供了常见的数学计算
是一个典型的工具类,提供的都是静态方法
常见方法
- random,返回一个随机数,范围为 0.0 =< 随机值< 1.0
- round 返回入参的四舍五入的整数值
- floor,返回入参的地板值
- ceil,返回入参的天花板值
- abs,返回入参的绝对值
- pow, 返回第一个入参的第二个入参的次方
- sqrt 返回参数的算术平方根
- ...
应用实例
应用实例1,常用方法
实例代码
package com.bjpowernode.demo;
/**
* Math类
*/
public class MathDemo {
public static void main(String[] args) {
//random,随机值
System.out.println("---------------random,随机值---------------");
double rndFirst = Math.random();
System.out.println("[0,1):"+rndFirst);
int rndSecond = (int) (Math.random()*100);
System.out.println("[0,100):"+rndSecond);
//round,四舍五入
System.out.println("---------------round,四舍五入---------------");
double roundData = 1.53701;
System.out.println("Math.round("+roundData+")="+Math.round(roundData));
System.out.println("Math.round("+roundData+"*100)="+Math.round(roundData*100));
System.out.println("Math.round(-"+roundData+")="+Math.round(-roundData));
//floor,地板值
double floorData = 1.99999;
System.out.println("---------------floor,地板值---------------");
System.out.println("Math.floor("+floorData+")="+Math.floor(floorData));
//ceil,天花板值
double ceilData = 1.0001;
System.out.println("---------------ceil,天花板值---------------");
System.out.println("Math.ceil("+ceilData+")="+Math.ceil(ceilData));
//abs,绝对值
int absData = -250;
System.out.println("---------------abs,绝对值---------------");
System.out.println("Math.abs("+absData+")="+Math.abs(absData));
//pow,次方
System.out.println("---------------pow,次方---------------");
System.out.println("Math.pow(2,8)="+Math.pow(2,8));
//sqrt,平方根
System.out.println("---------------sqrt,平方根---------------");
System.out.println("Math.sqrt(16)="+Math.sqrt(16));
}
}输出结果,运行查看结果
【练习】
- 练习演示的内容,完成代码编写
UUID类
通用唯一识别码(Universally Unique Identifier),也称全局唯一标识符,由一组32位的十六进制数组成
根据机器的物理地址、时间戳等构成,可以保证全球范围内的唯一,常在一些中小系统中作为数据标识的主键 ,简单、易用
在各个领域,有着广泛的应用
一些中小型的业务系统,主键会使用UUID
是一个典型的工具类,提供的都是静态方法
常用方法
- randomUUID,返回一个随机UUID
- from,从字符串生成UUID对象
- nameUUIDFromBytes,根据字节数组获取UUID对象
应用实例
应用实例1,常用方法
实例代码
package com.bjpowernode.demo;
import java.util.UUID;
/**
* UUID类
*/
public class UUIDDemo {
public static void main(String[] args) {
//randomUUID,随机UUID
System.out.println("UUID.randomUUID()="+UUID.randomUUID());
//from,从字符串生成UUID对象
UUID uuid = UUID.fromString("44399c7b-f66e-4b74-babc-0ee1ae24060e");
System.out.println("UUID.fromString(\"44399c7b-f66e-4b74-babc-0ee1ae24060e\")="+uuid);
//nameUUIDFromBytes,根据字节数组获取UUID对象
uuid = UUID.nameUUIDFromBytes("Java的世界".getBytes());
System.out.println("UUID.nameUUIDFromBytes(\"Java的世界\".getBytes())="+uuid);
}
}输出结果,运行查看结果
【练习】
- 练习演示的内容,完成代码编写
Java API文档
概述
JDK的工具中,提供了一个JavaDoc工具,用于生成代码的API文档
JavaDoc工具会对指定类的各类注释,以及注释中的可识别标签,生成对应的阅读性更强的文档,方便使用程序的开发人员
可识别的标签如下
可识别标签(图片来自网络)
使用方式
注意:下在两种方式,使用附件中的store-house-javadoc项目演示
方式1,使用javadoc命令生成
在命令行窗口,类源代码所在文件位置,使用如下命令生成API文档
javadoc -encoding UTF-8 -charset UTF-8 *.java
此时,会在当前目录生成很多.html的文件,打开index.html,就可看到生成的API文档,如下图
方式2,使用IDEA生成
在点击菜单Tools->Generate JavaDoc...打开的弹窗中,指定好Output directory、Locale、Other command line arguments后,再点击OK即可,具体内容如下图
此时,会在指定目录生成很多.html的文件,打开index.html,就可看到生成的API文档,如下图
JDK的API文档
- 每个JDK版本发布后,里面都有众多的类,官方亦会提供专业的JavaDoc API文档
- 可在线查看,JDK1.8的地址:https://docs.oracle.com/javase/8/docs/api/
【练习】
- 练习演示的内容,熟悉如何生成JavaDoc文档,如何使用官方文档
打包和部署【扩展】
概述
- 程序开发完成后,需要打包、并发布到应用服务器上,或提供给别的项目使用
- 通常项目打包成.jar包,部分Web项目会打包成.war包
步骤
下面使用本章附件的kfc-suite项目为演示
点击File菜单下的Project Stucture..
在Project Stucture...弹窗中,选择Artifacts菜单,并点击+号,添加一个打包项目
会打开 一个打包类型选择的子菜单,在菜单中,选择JAR->From modules with dependencies...
会继续打开一个Create JAR from Modules子弹窗,点击Main Class后的文件夹图标
就进入了Select Main Class子弹窗,选择main方法所在的入口类,然后依次点击OK
回到Project Stucture弹窗中,当前项目打包成jar包的配置就完成了,点击OK结束配置回到主界面;其中红框就是打包的.jar包的文件位置
回到项目主界面后,点击Build菜单下的Build Artifacts...菜单
会再次在主界面中央弹出一个子菜单,点击Build,将会往第6步配置红圈指定的目录位置生成.jar打包文件
进入项目所在目录下的out目录的指定位置,就能找到打包好的.jar包
最后,将打包好的.jar包,拷贝到任意安装有JRE的服务器上进行部署或给到其他项目使用;如果是直接部署,使用命令就能运行当前项目了,具体命令如下
java -jar xxx.jar
【练习】
- 练习演示的内容,完成项目打包和部署
使用依赖包【扩展】
概述
- 任何的应用程序,都不可能从0开始写所有的功能,都会使用Java语言的基础包、第三方依赖包、自定义依赖包
- 第三方依赖包和自定义依赖包,多以.jar包形式存在
- 使用第三方依赖包的方式有多种,下面介绍一个项目常用的方式
步骤
下面使用打包和部署中附件的kfc-suite项目作为依赖包,kfc-suite-client作为当前项目
在当前项目下创建lib目录
将依赖包.jar文件拷贝到lib目录
此时,在IDEA主界面的左侧项目窗口中,将会看到加入的lib目录和.jar依赖包;在lib目录上点击右键,选择Add as Library...
在弹出的Create Library弹窗中,点击确定;依赖包就添加成功了
此时,在当前项目中,就能像使用自己的类和接口一样,使用依赖包中的类、接口等其他内容,像如下代码
【练习】
- 练习演示的内容,完成使用依赖包
类和类之间的关系【扩展】
在实际的项目中,会有着众多的类、接口,这些类、接口协同工作,完成很多复杂的业务
同样,随着学习的深入,需要对类间关系,有更深入的了解和认识,并在不同的应用场景做不同的处理
类和类之间的关系由强到弱分为:泛化=实现>组合>聚合>关联>依赖
工作中,比较好的实践是,尽量要降低类之间的关系
如下图,通过UML类图展现了实际项目中类间常用的关系;代码示例见附件中的class-relation.rar
类与类间关系