跳到主要内容

第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));
    }
    }

【练习】

  1. 练习演示的内容,完成代码编写

传值和传引用

概述

  • 在实际的应用过程中,经常会涉及到方法调用过程中的参数数据传递
  • 参数数据传递,针对基本数据类型、引用数据类型还有一定的差异

传值

问题:下面的代码,在方法调用后,将输出什么内容?

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;
      }
      }

【练习】

  1. 练习演示的内容,完成代码编写

字符串相关

概述

  • 由于字符串处理的使用频率非常高,相应的字符串处理的方式与机制也很多
  • 除了熟悉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());
        }
        }

        输出结果,编号、体重、工资并不符合要求

        Java常用类-字符串-未格式化

  • 引入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);
        }

        输出结果,编号、体重、工资符合要求

        Java常用类-字符串-已格式化

  • 具体语法如下

    Java常用类-字符串-String.format格式

    String.format格式化语法

【练习】

  1. 练习演示的内容,完成代码编写

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效果、方法都类似
  • 特点:
    • 效率高
    • 更灵活
    • 线程安全

【演示】

  1. 时间对比,查看运行效果

    1. 使用+拼接

      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+"毫秒");
      }
      }
    2. 使用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 + "毫秒");
      }
      }

【练习】

  1. 练习应用实例内容,完成代码编写
  2. 自己学习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));
    }
    }

【练习】

  1. 练习演示的内容,完成代码编写

与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));
    }
    }

【练习】

  1. 练习演示的内容,完成代码编写

日期和时间

概述

  • 在实际的业务中,日期/时间的处理,也是常见的,如人员的生日,数据记录时的创建时间、更新时间等
  • 随着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);
        }
        }

        输出结果,运行查看结果

    • 常用格式化规则

      Java常用类-日期时间相关-日期格式

      日期/时间格式化规则(图片来自网络)

【练习】

  1. 练习演示的内容,完成代码编写

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));
      }
      }

      输出结果,运行查看结果

【练习】

  1. 练习演示的内容,完成代码编写

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));
          }
          }

          输出结果,运行查看结果

    【练习】

    1. 练习演示的内容,完成代码编写

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));
      }
      }

      输出结果,运行查看结果

    【练习】

    1. 练习演示的内容,完成代码编写

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);
      }
      }

      输出结果,运行查看结果

【练习】

  1. 练习演示的内容,完成代码编写

Java API文档

概述

  • JDK的工具中,提供了一个JavaDoc工具,用于生成代码的API文档

  • JavaDoc工具会对指定类的各类注释,以及注释中的可识别标签,生成对应的阅读性更强的文档,方便使用程序的开发人员

  • 可识别的标签如下

    补充-Javadoc

    可识别标签(图片来自网络)

使用方式

注意:下在两种方式,使用附件中的store-house-javadoc项目演示

  • 方式1,使用javadoc命令生成

    • 在命令行窗口,类源代码所在文件位置,使用如下命令生成API文档

      javadoc -encoding UTF-8 -charset UTF-8 *.java
    • 此时,会在当前目录生成很多.html的文件,打开index.html,就可看到生成的API文档,如下图

      补充-Javadoc-API

  • 方式2,使用IDEA生成

    • 在点击菜单Tools->Generate JavaDoc...打开的弹窗中,指定好Output directory、Locale、Other command line arguments后,再点击OK即可,具体内容如下图

      补充-Javadoc-generate

    • 此时,会在指定目录生成很多.html的文件,打开index.html,就可看到生成的API文档,如下图

      补充-Javadoc-API

JDK的API文档

【练习】

  1. 练习演示的内容,熟悉如何生成JavaDoc文档,如何使用官方文档

打包和部署【扩展】

概述

  • 程序开发完成后,需要打包、并发布到应用服务器上,或提供给别的项目使用
  • 通常项目打包成.jar包,部分Web项目会打包成.war包

步骤

下面使用本章附件的kfc-suite项目为演示

  1. 点击File菜单下的Project Stucture..

    补充-打包-步骤-1

  2. 在Project Stucture...弹窗中,选择Artifacts菜单,并点击+号,添加一个打包项目

    补充-打包-步骤-2

  3. 会打开 一个打包类型选择的子菜单,在菜单中,选择JAR->From modules with dependencies...

    补充-打包-步骤-3

  4. 会继续打开一个Create JAR from Modules子弹窗,点击Main Class后的文件夹图标

    补充-打包-步骤-4

  5. 就进入了Select Main Class子弹窗,选择main方法所在的入口类,然后依次点击OK

    补充-打包-步骤-5

  6. 回到Project Stucture弹窗中,当前项目打包成jar包的配置就完成了,点击OK结束配置回到主界面;其中红框就是打包的.jar包的文件位置

    补充-打包-步骤-6

  7. 回到项目主界面后,点击Build菜单下的Build Artifacts...菜单

    补充-打包-步骤-7

  8. 会再次在主界面中央弹出一个子菜单,点击Build,将会往第6步配置红圈指定的目录位置生成.jar打包文件

    补充-打包-步骤-8

  9. 进入项目所在目录下的out目录的指定位置,就能找到打包好的.jar包

    补充-打包-步骤-9

  10. 最后,将打包好的.jar包,拷贝到任意安装有JRE的服务器上进行部署或给到其他项目使用;如果是直接部署,使用命令就能运行当前项目了,具体命令如下

    java -jar xxx.jar

【练习】

  1. 练习演示的内容,完成项目打包和部署

使用依赖包【扩展】

概述

  • 任何的应用程序,都不可能从0开始写所有的功能,都会使用Java语言的基础包、第三方依赖包、自定义依赖包
  • 第三方依赖包和自定义依赖包,多以.jar包形式存在
  • 使用第三方依赖包的方式有多种,下面介绍一个项目常用的方式

步骤

下面使用打包和部署中附件的kfc-suite项目作为依赖包,kfc-suite-client作为当前项目

  1. 在当前项目下创建lib目录

  2. 将依赖包.jar文件拷贝到lib目录

    补充-使用依赖包-步骤-2

  3. 此时,在IDEA主界面的左侧项目窗口中,将会看到加入的lib目录和.jar依赖包;在lib目录上点击右键,选择Add as Library...

    补充-使用依赖包-步骤-3

  4. 在弹出的Create Library弹窗中,点击确定;依赖包就添加成功了

    补充-使用依赖包-步骤-4

  5. 此时,在当前项目中,就能像使用自己的类和接口一样,使用依赖包中的类、接口等其他内容,像如下代码

    补充-使用依赖包-步骤-5

【练习】

  1. 练习演示的内容,完成使用依赖包

类和类之间的关系【扩展】

  • 在实际的项目中,会有着众多的类、接口,这些类、接口协同工作,完成很多复杂的业务

  • 同样,随着学习的深入,需要对类间关系,有更深入的了解和认识,并在不同的应用场景做不同的处理

  • 类和类之间的关系由强到弱分为:泛化=实现>组合>聚合>关联>依赖

  • 工作中,比较好的实践是,尽量要降低类之间的关系

  • 如下图,通过UML类图展现了实际项目中类间常用的关系;代码示例见附件中的class-relation.rar

    补充-类与类之间的关系

    类与类间关系