当前位置: 首页>JAVA>正文

java log info亂碼_跟光磊學Java開發-Java開發常用API的使用

java log info亂碼_跟光磊學Java開發-Java開發常用API的使用

Object類

Object類概述

java.lang.Object類是所有Java類的根類,即所有子類都會直接或者間接繼承(Extends)Object類,直接繼承是不用寫extends Object,編譯器會自動添加。java.lang包下的類在使用時不需要使用import關鍵字導入。
因為Object類是根類,不需要考慮它的繼承關系,因此只需要去看看它有哪些方法即常用的方法即可,因為所有的子類都會擁有Object類的方法。

Object類所有的方法

5ae05fe74bde389edf5b0e73a26a70d4.png

如果你封裝了一個JavaBean(即私有化成員變量,提供get/set方法和無參構造器的類),會使用到其父類Object的equals()方法和、oString()方法和hashCode()方法
而notify()方法,notifyAll()方法,wait()方法是多線程情況下使用。getClass()方法是反射特性會使用。

Employee JavaBean設計

Employee 是一個普通的JavaBean,包含三個私有化成員變量以及get/set方法以及構造方法,該類會默認繼承java.lang.Object,因此會有父類的方法

package net.ittimeline.java.core.jdk.api.lang.bean;/** * 員工類 默認會繼承java.lang.Object * * @author tony 18601767221@163.com * @version 2020/12/16 12:58 * @since JDK11 */public class Employee {    /*************************私有化成員變量*****************************************/    /**     * 員工編號     */    private String employeeNo;    /**     * 姓名     */    private String name;    /**     * 年齡     */    private Integer age;    /**     * 默認無參數構造器     */    public Employee(){}    /**     * 全參數構造器     * @param employeeNo     * @param name     * @param age     */    public Employee(String employeeNo, String name, Integer age) {        this.employeeNo = employeeNo;        this.name = name;        this.age = age;    }    /**************************get/set方法*****************************************/    public String getEmployeeNo() {        return employeeNo;    }    public void setEmployeeNo(String employeeNo) {        this.employeeNo = employeeNo;    }    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public Integer getAge() {        return age;    }    public void setAge(Integer age) {        this.age = age;    }}

toString()方法的使用

toString()方法就是返回該對象的字符串表示,默認是返回的對象的全路徑名+@加對象地址。

Object類的toString()方法實現

  public String toString() {        return getClass().getName() + "@" + Integer.toHexString(hashCode());    }

當打印輸出對象時默認會調用對象的toString()方法

    /**     * 測試Employee類默認的toString()默認方法,該方法返回對象的字符串     * toString()方法默認會打印 類的全路徑+@+對象的地址值   net.ittimeline.java.core.jdk.api.lang.bean.Employee@25e2ab5a     * @see Object#toString()      */    @Test    public void tesEmployeeDefaultToStringMethod(){        Employee employee=new Employee();        //當打印對象時默認會調用對象的toString()方法        log.info("employee = {}",employee);        log.info("employee.toString() = {}",employee.toString());    }

程序運行結果

f243ae34882b627b319ad0530c0700de.png


因為Employee類是我們自己封裝的一種數據類型,在進行業務系統開發時通常會查看對象的成員變量(也叫屬性)值,而不關心對象的全類名和內存地址。
因此一般都會去重寫java.lang.Object父類的toString()方法。

  /**     * 重寫父類java.lang.Object的toString()方法     * @return 對象的屬性信息的字符串     * @see Object#toString()      */    @Override    public String toString() {        return "Employee{" +                "employeeNo='" + employeeNo + ''' +                ", name='" + name + ''' +                ", age=" + age +                '}';    }

重寫toString()方法以后,會打印對象的屬性值

 /**     * 測試重寫父類java.lang.Object的toString()方法     */    @Test    public  void testEmployeeOverrideObjectToStringMethod(){        Employee employee=new Employee();        employee.setEmployeeNo("ittimeline00001");        employee.setName("tony");        employee.setAge(28);        //當打印對象時默認會調用對象的toString()方法        log.info("employee = {}",employee);        log.info("employee.toString() = {}",employee.toString());    }

程序運行結果

848069d0025ee8d6a18d76a439f52d1e.png

JDK提供的API也都重寫了java.lang.Object類的toString()方法

StringBuilder重寫toString()方法

157015af5cb0d1cb4510c362b3f0219d.png

String類重寫toString()方法

2de3d7ad379fbce5580c591df2576fb1.png

equals()方法的使用

java.lang.Object類的equals()方法使用==來判斷兩個對象是否相等,該方法需要傳遞一個Object類對象的參數,返回一個布爾值,如果相等則返回true,不等則返回false

  public boolean equals(Object obj) {        return (this == obj);    }

java.lang.Object類的equals()方法比較的是地址是否相等,但是日常開發中通常比較的是對象的成員變量值是否相等,如果屬性值不相等則返回false

   /**     *  父類java.lang.Object的equals()方法使用==判斷兩個對象的地址是否像等,如果地址不相等返回false     */    @Test    public void testEmployeeDefaultEqualsMethod(){        //創建兩個Employee對象        Employee ittimeline00001=new Employee();        ittimeline00001.setEmployeeNo("ittimeline00001");        ittimeline00001.setName("tony");        ittimeline00001.setAge(28);        Employee ittimeline00002=new Employee();        ittimeline00002.setEmployeeNo("ittimeline00001");        ittimeline00002.setName("tony");        ittimeline00002.setAge(28);        log.info("ittimeline00001 == ittimeline00002  {}",(ittimeline00001==ittimeline00002));        //ittimeline00002 是Object類的子類對象,因此可以使用參數多態作為equals()方法的參數        log.info("ittimeline00001.equals(ittimeline00002) =   {}",(ittimeline00001.equals(ittimeline00002)));    }

程序運行結果

18b00a716880eb81efce05c3d74943a6.png

因此如果想要判斷對象的屬性值是否相等,我們還需要重寫java.lang.Object類的equals()方法,一般重寫equals()方法都要重寫hashCode()方法。

  /**     * 重寫java.lang.Object的equals()方法     * @param object     * @return     * @see Object#equals(Object)      */    @Override    public boolean equals(Object object) {        //如果兩個對象的地址相等則返回true        if(this==object){            return true;        }        //方法的參數為空或者類型不一樣返回false        if(null==object||this.getClass()!=object.getClass()){            return false;        }        Employee targetEmployee= (Employee) object;        //判斷如果員工編號一樣就表示同一個員工        return Objects.equals(this.getEmployeeNo(),targetEmployee.getEmployeeNo());    }    @Override    public int hashCode() {        return Objects.hash(employeeNo, name, age);    }

重寫后再次創建兩個對象并分別調用==和equals()方法來判斷兩個對象的相等性

  /**     *  測試重寫父類java.lang.Object的equals()方法     */    @Test    public void testEmployeeOverrideObjectEqualsMethod(){        //創建兩個Employee對象        Employee ittimeline00001=new Employee();        ittimeline00001.setEmployeeNo("ittimeline00001");        ittimeline00001.setName("tony");        ittimeline00001.setAge(28);        Employee ittimeline00002=new Employee();        ittimeline00002.setEmployeeNo("ittimeline00001");        ittimeline00002.setName("tony");        ittimeline00002.setAge(28);        log.info("ittimeline00001 == ittimeline00002  {}",(ittimeline00001==ittimeline00002));        //ittimeline00002 是Object類的子類對象,因此可以使用參數多態作為equals()方法的參數        log.info("ittimeline00001.equals(ittimeline00002) =   {}",(ittimeline00001.equals(ittimeline00002)));    }

程序運行結果
程序運行結果表明重寫equals()方法以后,==判斷的返回結果是false,而equals()方法返回的是true

4ed093f3489245a8e1915dcb08aa5bc0.png

看到這里讀者應該能夠解決一個面試題: ==和equals()方法有什么區別。回答該問題時應該先考慮未重寫equals()前的行為和重寫equals()后的行為。

Objects類

java.util.Objects類是JDK7以后新增的一個工具類,該類包含許多關于Object操作的靜態方法,也就是可以直接通過類名.方法名調用。

3c7ba2714e420f5b1c8014887b955e21.png


java.util.Objects類提供的方法都是空指針安全的,也就是能夠避免空指針異常。日常開發中應該盡量避免空指針異常。
我們可以學習Objects類的equals()方法的實現,如果避免空指針異常。

 public static boolean equals(Object a, Object b) {        return (a == b) || (a != null && a.equals(b));    }

equals()方法需要兩個Object類型的參數,通常是傳遞的自己封裝的類的成員變量。
equals()該方法的執行流程是

  1. 判斷兩個對象的地址是否相同,如果相同根據邏輯或的短路特性,直接返回true
  2. 如果兩個對象的地址不同,則會判斷第一個參數a是不是空,如果為空則會根據邏輯與的短路特性直接返回false
  3. 如果a不為空則調用兩個參數的equals()方法來判斷是否相等

在沒有Objects提供的equals()方法前,如果使用JDK提供的API的equals()方法容易引發空指針異常

  //測試String對象的相等性判斷  @Test  public void testStringEquals(){    // 使用String類的equals()進行相等性判斷容易引發空指針    String str1 = null;    String str2 = "tony";     log.info("str1 .equals(str2) = {}", str1.equals(str2));  }

程序運行結果

a06c8fb2e759a2677f01ab8b43cb847d.png

此時可以使用Objects提供的equals()方法來判斷String的相等性

/**   * 使用Objects.equals()方法判斷String相等性   */  @Test  public void testObjectsStringEquals(){    String str1 = null;    String str2 = "tony";    log.info("Objects.equals(str1,str2) = {}", Objects.equals(str1, str2));    String str3="tony";    log.info("Objects.equals(str3,str2) = {}", Objects.equals(str3, str2));    String str4=new String("tony");    log.info("Objects.equals(str4, str2) = {}", Objects.equals(str4, str2));  }

程序運行結果

38d76c8b9622977c3294d874a6f8dbcb.png

因此后面在日常開發中應該是用java.util.Objects類提供的equals()方法來比較兩個對象是否相等。這樣能夠避免空指針異常。

因為Objects的equals()方法需要兩個Object類型的參數,因此根據形參多態的特性,所有的Object子類都可以做為該方法的參數

  /**   * 使用Objects.equals()方法判斷兩個Employee對象是否相等   */  @Test  public void testEmployeeObjectsEqualsMethod() {    //創建兩個不同屬性值的Employee對象    Employee ittimeline00001=new Employee();    ittimeline00001.setEmployeeNo("ittimeline00001");    ittimeline00001.setName("tony");    ittimeline00001.setAge(28);    Employee ittimeline00002=new Employee();    ittimeline00002.setEmployeeNo("ittimeline00002");    ittimeline00002.setName("jack");    ittimeline00002.setAge(27);   boolean equalsResult= Objects.equals(ittimeline00001,ittimeline00002);   log.info("equalsResult = {}",equalsResult);   Employee ittimeline00003=ittimeline00001;     equalsResult= Objects.equals(ittimeline00001,ittimeline00003);    log.info("equalsResult = {}",equalsResult);  }

程序運行結果

5e461725093926c53d57ccf6d6389143.png

native 方法

native方法稱為本地方法,本地方法沒有方法體,我們也無法查看其實現,當我們需要訪問C/C或者訪問操作系統底層的類庫時可以使用本地方法實現,也意味著Java語言可以通過JNI和其他語言進行交互。
本地方法的作用就是當Java調用非Java代碼的接口時,方法的實現是非Java實現,通常都是C/C
實現。
Object類中的getClass(),hashCode(),notify(),notifyAll(),wait()都是使用C/C++實現的本地方法

    public final native Class> getClass();public native int hashCode();    public final native void notify();    public final native void notifyAll();public final native void wait(long timeoutMillis) throws InterruptedException;

時間日期類

Date類

Date類表示日期,時間精確到毫秒。
Date類是JDK1.0設計的類,因為其本身有些缺陷,在Java8重新設計了一套日期API,因此Date類的很多方法都已經標記為過時了,如果方法上有個@Deprecated注解就表示該方法已經過時,在日常開發中盡量避免使用過時的方法,因為JDK或者框架會在后期的版本升級中刪除過時的方法,那樣我們的程序會無法編譯通過。

f0eaf14f86ba3489c27e95835175a7df.png

Date類有兩個常用的構造函數

public Date() {        this(System.currentTimeMillis());    }   public Date(long date) {        fastTime = date;    }

其中無參數的構造器是以當前的時間創建日期對象

 /**     * 測試無參數的構造器     */    @Test    public void testDateNoArgsConstructMethod(){        /**         * 默認以當前時間創建日期對象         */        Date currentDate=new Date();        //Wed Dec 16 15:29:07 CST 2020        // CST 表示中國標準時間        // Dec 16 表示12月16日        // Wed 表示星期三        System.out.println(currentDate);    }

程序運行結果

840bef31eb79f325bca45c4ecfa40d8b.png

而傳long參數的構造器用創建一個以標準時間為基準,指定偏移毫秒數對應的日期對象

  • 標準時間指的是1970年1月1日 00:00:00 ,也就是Unix系統的誕生日,而我們偉大的祖國母親是位于東八區,因此標準時間是1970年1月1日:08:00:00
 @Test    public void testDateLongArgsConstructMethod(){        /**         * 以標準基準時間為基準,指定偏移毫秒數對應的日期對象         * 標準基準時間是格林威治時區: 1970年1月1日 00:00:00         * 中國處于東八區:     1970年1月1日:08:00:00         */        Date offSetDate=new Date(1000);        //Thu Jan 01 08:00:01 CST 1970        System.out.println(offSetDate);    }

程序運行結果

5379819df1cb42ac38aa918056b9e6a0.png

Date類還提供了getTime()獲取標準當前日期距離標準基準時間的毫秒數,該方法的返回值可以用于統計程序的時間耗時,作為程序性能優化的依據,setTime()用于置當前日期對象距離標準基準時間的毫秒數

    @Test    public void testDateGetTimeMethod(){        Date now=new Date();        //獲取當前日期對象距離標準基準時間的毫秒數        long milliseconds=now.getTime();        log.info("獲取當前日期對象距離標準基準時間的毫秒數 {}",milliseconds);        //設置當前日期對象距離標準基準時間1970年1月1日:08:00:00的毫秒數        now.setTime(2000);        System.out.println("now = "+now);    }

程序運行結果

1f0eadda98435fe4ceeca60900d30e22.png

Date類還提供了before()和after()方法用于比較兩個日期

  @Test    public void testDateBeforeAfterMethod(){        //以當前時間創建日期對象        Date currentDate=new Date();        System.out.println("currentDate = "+currentDate);        //從1970-01-01 08:00:00 加2000毫秒 1970-01-01 08:00:02        Date customDate=new Date(2000);        System.out.println("customDate = "+customDate);        log.info("customDate.before(currentDate) = {}",customDate.before(currentDate));        log.info("customDate.after(currentDate) = {}",customDate.after(currentDate));    }

程序運行結果

9213e46460329c6873e09366effe4403.png

DateFormat類

java.text.DateFormat類是一個日期/時間格式化的抽象類,其應用場景是當Web前端傳遞過來的日期都是字符串形式,Java后端接收時需要按照指定的格式進行日期轉換后存儲到數據庫。
由于DateFormat是一個抽象類,因此需要使用該類的子類SimpleDateFormat來實現日期/時間格式化。也就是將字符串日期和Date日期相互轉換。

2c9eecbe15239a1729dfe7232ba673af.png

在創建SimpleDateFormat對象時需要傳入指定的日期格式參數

public SimpleDateFormat(String pattern)    {        this(pattern, Locale.getDefault(Locale.Category.FORMAT));    }

常用的日期格式有yyyy年MM月dd日 HH時mm分ss秒和 yyyy-MM-dd HH:mm:ss

  • y 表示年
  • M 表示月
  • d 表示日
  • HH 表示小時
  • mm 表示分鐘
  • ss 表示秒鐘

SimpleDateFormat提供了format()方法用于將日期轉換為字符串

    /**     * 標準日期格式常量     */    public static final String DEFAULT_PATTERN="yyyy-MM-dd HH:mm:ss";   /**     *     * 使用SimpleDateFormat的format()方法實現日期轉字符串     *     */    @Test    public void testSimpleDateFormatDateToString(){        //按照指定的日期格式創建日期格式化對象        DateFormat dateFormatDefaultPattern =new SimpleDateFormat(DEFAULT_PATTERN);        //調用format()方法將日期轉換為字符串        //日期對象使用的是匿名對象        String defaultPatternDateToStr=dateFormatDefaultPattern.format(new Date());        log.info("defaultPatternDateToStr = {}",defaultPatternDateToStr);    }

程序運行結果

d0b13ec13b02bd787edfc8376389ba50.png

SimpleDateFormat提供了parse()方法用以將字符串轉換為日期

    /**     * 使用SimpleDateFormat的parse()方法將日期轉換為字符串     * @throws ParseException     */    @Test    public void testSimpleDateFormatStringToDate()throws ParseException{        //創建日期字符串      String dateStr= "2020-12-16 16:02:00";      //按照指定的格式創建日期格式化對象      DateFormat dateFormatDefaultPattern =new SimpleDateFormat(DEFAULT_PATTERN);      //通過parse()方法講將字符串轉換為日期對象      Date stringToDateResult =dateFormatDefaultPattern.parse(dateStr);      System.out.println("stringToDateResult = "+stringToDateResult);    }

程序運行結果

e09b210c242d04e7e63b79b73e232363.png

一個日期和格式化的案例:從鍵盤讀取用戶輸入的生日,然后計算天數

程序實現思路

  1. 創建Scanner對象調用netxtLine()方法獲取用戶輸入的生日字符串
  2. 使用SimpleDateFormat的parse()方法將生日字符串轉換為Date日期
  3. 調用Date日期對象的getTime()方法獲取系統基準時間到生日的毫秒數
  4. 調用當前日期對象額getTime()方法獲取系統基準時間到當前時間的毫秒數
  5. 當前時間的毫秒數減去生日毫秒數后求天數。

程序實現代碼

package net.ittimeline.java.core.jdk.api.text;import java.text.DateFormat;import java.text.ParseException;import java.text.SimpleDateFormat;import java.util.Date;import java.util.Scanner;/** * 從鍵盤讀取用戶輸入的生日,然后計算天數 * * @author tony 18601767221@163.com * @version 2020/12/16 16:24 * @since JDK11 */public class DateFormatBirthdayCalculatorTest {  public static void main(String[] args) throws ParseException {      Scanner input =new Scanner(System.in);      System.out.println("請輸入你的生日(格式為 yyyy-MM-dd)");      String birthdayStr=input.nextLine();      DateFormat dateFormat=new SimpleDateFormat("yyyy-MM-dd");      Date birthdayDate=dateFormat.parse(birthdayStr);      long birthdayMilliseconds= birthdayDate.getTime();      long currentMilliseconds=new Date().getTime();      long day=(currentMilliseconds-birthdayMilliseconds)/1000/60/60/24;      System.out.printf("你已經來到這個世界%d天了",day);      input.close();  }}

程序運行結果

f9254e493e0a477bb4195a9172f0b65a.png

Calendar類

java.uti.Calendar是一個抽象類,用于表示日歷,包含日日期/時間信息,可以進行日期的運算。

415653dc99512cb99701b236a54a2b37.png


Calendar不能創建對象,一般是使用它的子類:java.util.GregorianCalendar類

29f13f0639bf21b66a8d6eb4a3459dae.png

有兩種方法可以創建GregorianCalendar對象

  /**   * 獲取日歷對象的兩種方法   */  @Test  public void testCreateCalendar() {    // 當前系統時間的日歷對象    Calendar calendarInstance = Calendar.getInstance();    Calendar calendar=new GregorianCalendar();    System.out.println(calendar);  }

當創建GregorianCalendar對象后打印輸出該對象會看到如下信息

1cc23837b49b6cc08c0ab7e4e99c202b.png
java.util.GregorianCalendar[time=1608110761595,areFieldsSet=true,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id="Asia/Shanghai",offset=28800000,dstSavings=0,useDaylight=false,transitions=31,lastRule=null],firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=1,YEAR=2020,MONTH=11,WEEK_OF_YEAR=51,WEEK_OF_MONTH=3,DAY_OF_MONTH=16,DAY_OF_YEAR=351,DAY_OF_WEEK=4,DAY_OF_WEEK_IN_MONTH=3,AM_PM=1,HOUR=5,HOUR_OF_DAY=17,MINUTE=26,SECOND=1,MILLISECOND=595,ZONE_OFFSET=28800000,DST_OFFSET=0]

關于GregorianCalendar對象關于日期/時間的屬性名/屬性值說明

  • time=1608110761595 表示當前時間距離標準基準時間的毫秒數
  • ZoneInfo 用于描述時區信息,當前時區是亞洲/上海,比標準基準時間晚8個小時
  • MONTH=11 表示今天是今年的12月份,GregorianCalendar對象的月分是從0開始
  • WEEK_OF_YEAR=51 表示今天是今年的51周
  • WEEK_OF_MONTH=3 表示今天是這個月的第三周
  • DAY_OF_WEEK=4 表示今天是這周的第四天,因為外國是從周日到周六,也就是說周日是一周的第一天,而今天(2020/12/16)按照外國人的算法就是周四
  • DAY_OF_MONTH=16 表示今天是這個月的16天
  • DAY_OF_YEAR=351 表示今天是今天的351天,難過的2020馬上就要結束了
  • DAY_OF_WEEK_IN_MONTH=3 表示今天是這個月的第三周

GregorianCalendar 提供了get()方法用于獲取日歷的日期/時間信息

  /**   * 通過GregorianCalendar對象的get方法獲取日歷的日期/時間信息   *   * @see GregorianCalendar#get(int)   */  @Test  public void testCalendarGetMethod() {    // 當前系統時間的日歷對象    Calendar calendarInstance = Calendar.getInstance();    int year = calendarInstance.get(Calendar.YEAR);    int month = calendarInstance.get(Calendar.MONTH);    int day = calendarInstance.get(Calendar.DAY_OF_MONTH);    int hour=calendarInstance.get(Calendar.HOUR_OF_DAY);    int minute = calendarInstance.get(Calendar.MINUTE);    int second=calendarInstance.get(Calendar.SECOND);    System.out.printf("通過GregorianCalendar對象的get()方法獲取日期信息:%d年%d月%d日 %d時%d分%d秒", year, month, day,hour,minute,second);  }

程序運行結果

febb59d88e63532da044ff1e19001fcc.png

GregorianCalendar 提供了set()方法設置指定的日期/時間,add()方法增加日期/時間

  /** 修改日歷對應日期 add 增加日期/時間 set 設置指定的日期/時間 */  @Test  public void testCalendarUpdate() {    Calendar calendarInstance = Calendar.getInstance();    // 將年份設置為1999    calendarInstance.set(Calendar.YEAR, 1999);    System.out.println("將年份設置為1999 當前年份是" + calendarInstance.get(Calendar.YEAR));    // 將當前的年份加兩年    calendarInstance.add(Calendar.YEAR, 2);    System.out.println("將當前的年份加兩年 當前年份是" + calendarInstance.get(Calendar.YEAR));    // 將當年的年份減少2年    calendarInstance.add(Calendar.YEAR, -2);    System.out.println("將當年的年份減少2年 當前年份是" + calendarInstance.get(Calendar.YEAR));  }

GregorianCalendar 還提供了setTime()的方法用于通過傳遞一個Date日期的參數來設置日歷

 /** 獲取距離標準時間2小時的日歷對象 */  @Test  public void testCalendarSetTimeMethod() {    Calendar calendarInstance = Calendar.getInstance();    // 首先獲取距離標準時間2小時的日期    Date date = new Date(1000 * 60 * 60 * 2);    // 調用日歷對象的setTime()方法設置日歷對象設置的日期    calendarInstance.setTime(date);    log.info(calendarInstance);  }

程序運行結果

a88c8c928b09cd90f2803fa934ffddd3.png

GregorianCalendar 也提供了用于兩個日歷對象的比較方法:before()和after()

/** before() 判斷此Calendar表示的時間是否在指定的Object表示的時間之前 ,返回布爾值。 */  @Test  public void testCalendarBefore() {    Calendar source = Calendar.getInstance();    System.out.printf("通過GregorianCalendar對象的get()方法獲取source日期信息:%d年%d月%d日", source.get(Calendar.YEAR), source.get(Calendar.MONTH), source.get(Calendar.DAY_OF_MONTH));    //以標準基準時間偏移24小時創建日歷對象    Calendar target = Calendar.getInstance();    Date date = new Date(1000 * 60 * 60 * 24);    target.setTime(date);    System.out.printf(        "通過GregorianCalendar對象的get()方法獲取target日期信息:%d年%d月%d日",        target.get(Calendar.YEAR), target.get(Calendar.MONTH), target.get(Calendar.DAY_OF_MONTH));    boolean beforeResult = source.before(target);    System.out.println("source.before(target)= "+beforeResult);    boolean afterResult = source.after(target);    System.out.println("source.after(target)= "+afterResult);  }

程序運行結果

332acbfc776b83e098a809ec25a5e254.png

Math類

java.lang.Math類提供了一些關于數學運算的靜態方法,即它的方法都是使用static修飾的,直接通過類名.方法名調用即可。

在日常開發中常用的Math提供的方法如下

  • Math.abs()求一個數值的絕對值
  /** Math.abs()求一個數值的絕對值 */  @Test  public void testMathAbsMethod() {    System.out.println("10的絕對值是"+Math.abs(10));    System.out.println("-10的絕對值是"+Math.abs(-10));    System.out.println("2.0的絕對值是"+Math.abs(2.0));    System.out.println("-2.0的絕對值是"+Math.abs(-2.0));  }

程序運行結果

bf6ec3704557f476e8fbf0ad35b5ed1c.png
  • Math.ceil() 向上取整
  • Math.floor() 向下取整
/** Math.ceil() 向上取整 大于這個數的最小整數 */  /** Math.floor() 向下取整 小于這個數的最小整數 */  @Test  public void testMathCeilFloorMethod() {    //3.2向上取整就是4.0    System.out.println("3.2向上取整的結果是"+Math.ceil(3.2));    //-3.2向上取整就是-3    System.out.println("-3.2向上取整的結果是"+Math.ceil(-3.2));    //3.2向下取整就是3.0    System.out.println("3.2向下取整的結果是"+Math.floor(3.2));  }

程序運行結果

7ad9570cf01f0c19fa4d633fe9d78770.png
  • Math.pow(m,n) 求m的n次冪
/**   * Math.pow(m,n) 計算m的n次方   */  @Test  public void testMathPowMethod() {    //計算2的3次方    System.out.println("2.0的3.0次冪的結果是"+Math.pow(2.0,3.0));  }

程序運行結果

08258b3e7507b7b715a75e0151c3c15f.png
  • Math.round() 四舍五入
  /**   * Math.round() 四舍五入   */  @Test  public void testMathRoundMethod() {    System.out.println("3四舍五入的結果是"+Math.round(3));    System.out.println("99四舍五入的結果是"+Math.round(99));    System.out.println("3.49四舍五入的結果是"+Math.round(3.49));    System.out.println("3.50四舍五入的結果是"+Math.round(3.50));  }

程序運行結果

8e51b845ef8741228fc9ec418cc58969.png
  • Math.max()求兩個數的最大值
  • Math.min() 求兩個數的最小值
 /**   * Math.max()獲取最大值   * Math.min()獲取最小值   */  @Test  public void testMatMaxMinMethod() {    System.out.println("10,20的最大值是"+Math.max(10,20));    System.out.println("10,20的最小值是"+Math.min(10,20));  }

程序運行結果

b4c2a857c36022d07da4d7ff63223fda.png

System類

java.lang.System類表示系統,不能實例化,因此該類提供了大量的靜態方法用于獲取或者去操作系統。

  • System.getProperty()方法來獲取系統的屬性
    首先使用System.getProperties().list(System.out);將所有的系統屬性輸出在終端后,使用System.getProperty()方法根據屬性名獲取屬性值
  /**   * 獲取系統屬性   */  @Test  public void testSystemGetProperties() {    //將所有的系統屬性輸出在終端上    System.getProperties().list(System.out);    System.out.println("當前Java程序依賴的JDK版本是"+System.getProperty("java.version"));    System.out.println("當前Java程序依賴的JVM是"+System.getProperty("java.vm.name"));    System.out.println("當前Java程序依賴的操作系統版本是"+System.getProperty("os.name"));    System.out.println("當前Java程序的字節碼版本是"+System.getProperty("java.class.version"));  }

程序運行結果

6334d8963984212c610b04b51020246b.png

程序運行結果

  • System.getenv()獲取系統所有環境變量
  /**   * 獲取系統環境變量   */  @Test  public void testSystemGetEnv() {    // 將所有的系統屬性輸出在終端上    System.out.println(System.getenv());    }

程序運行結果

c5c071e7bb56068713d961c5c62b28f7.png
  • System.arraycopy()方法實現數組的復制
@Test  public void testSystemArrayCopyMethod(){    int[]source={1,2,3,4,5,6,7,8};    int[] target={10,20,30,40,50,60,70,80};    //將source的5,6,7,8拷貝到target的50,60,70,80    System.arraycopy(source,4,target,4,4);    //輸出結果 [10, 20, 30, 40, 5, 6, 7, 8]    System.out.println("target = "+Arrays.toString(target));  }

程序運行結果

4622c71f8077061a235341124588e9ab.png
  • System.currentTimeMillis()方法用于獲取當前時間到標準基準時間的毫秒數,等價于調用Date對象的getTime()方法
  @Test  public void testSystemCurrentTimeMillisMethod(){    //獲取當前時間到標準基準時間的毫秒數    // 等價與new Date().getTime();    System.out.println(System.currentTimeMillis());    System.out.println(new Date().getTime());  }

程序運行結果

0f7cf5380970ae4e8374da0abb9cd1a3.png

我們可以基于System.currentTimeMillis()方法實現計算某段程序的耗時

 /**   * 統計程序耗時   */  @Test  public void tesSystemOutStatisticTime(){    long start=System.currentTimeMillis();    for (int i = 0; i <100; i++) {      System.out.println("i = "+i);    }    long end=System.currentTimeMillis();    log.info("程序耗時 {}毫秒",(end-start));  }

程序運行結果

10de4d86151d4d4ef6c885ff31851ef3.png

包裝類

之前學習的八種基本數據類型都不具備面向對象的特征:沒有屬性和方法,也沒法創建對象,更沒有面向對象的三大特征:封裝、繼承和多態。但是基本數據類型也有它的優勢,主要在于存儲方面。因此大佬們設計了8種基本數據類型的包裝類,包裝類就是將基本數據類型轉換為對應的引用數據類型。

  • byte的包裝類是java.lang.Byte
  • short的包裝類是java.lang.Short
  • char的包裝類是java.lang.Char
  • int的包裝類是java.lang.Integer
  • long的包裝類是java.lang.Long
  • float的包裝類是java.lang.Float
  • double的包裝類是java.lang.Double

這里以開發中常用的Integer類來說明包裝類的使用

Integer類定義了其占據的字節數,取值范圍的常量,如果你忘記了int的取值范圍,可以直接查看Integer類的源碼,或者直接通過Integer類調用對應的常量獲取

  /**   * Integer類定義了其占據的字節數,取值范圍的常量   */  @Test  public void testIntegerConstants(){    System.out.printf("int占據的字節數量是%d,int存儲的最小值是%d,int存儲的最大值是%d",Integer.BYTES,Integer.MIN_VALUE,Integer.MAX_VALUE);  }

Integer類也定義了方法用于實現將int和Integer的相互轉換

  • valueOf()方法實現將int轉換為Integer
  • intValue()方法實現將Integer轉換為int
 /** int和Integer的相互轉換 */  @Test  public void testIntegerCast() {    // 使用valueOf()方法將int轉換為Integer    Integer integer = Integer.valueOf(123);    System.out.println("integer = " + integer);    // intValue()方法將Integer轉換為int    int intValue = integer.intValue();    System.out.println("intValue = " + intValue);  }

程序運行結果

204aea9877681eb2e75a32208fbf6c81.png

但是日常開發中經常使用的是字符串和Integer之間的轉換,因為前臺傳過來的都是字符串類型的數據

  • parseInt()方法用于將字符串轉換為Integer
 @Test  public void testIntegerStringCast(){    // 使用valueOf()方法將String轉換為Integer    Integer value = Integer.valueOf("123");    System.out.println("value = " + value);    // 日常開發中常用的方法是將字符串轉換為Integer對象    Integer integerValue=Integer.parseInt("999");    System.out.println("integerValue = "+integerValue);  }

程序運行結果

81644f939dd2181cc18a1ce3b8f1da44.png

JDK1.5以后支持了自動拆箱和裝箱

  • 自動拆箱: 將包裝類自動轉換為對應的基本數據類型
  • 自動裝箱:將基本數據類型自動轉換為對應的包裝類類型
  /**   * 自動拆箱和裝箱   */  @Test  public void testAutoBox(){    //自動裝箱:將long自動轉換為java.lang.Long    Long longValueRef=70_00000000L;    //自動拆箱:將java.lang.Long自動轉換為long    long longValue=longValueRef;    System.out.printf("longValue = %d longValueRef = %d",longValue,longValueRef);  }

程序運行結果

61493b0dd0eae94c725bb6ee94a8b029.png

在日常開發中還會使用到基本數據類型和字符串之間的相互轉換

  • String.valueOf()靜態方法用于將基本數據類型轉換為String
  /**   * 基本數據類型轉換為String   */  @Test  public void testPrimitiveTypeCast(){    int intValue=123;    String stringValueInt=String.valueOf(intValue);    long longValue=123456789L;    String stringValueLong=String.valueOf(longValue);    System.out.printf("stringValueInt = %s stringValueLong = %s ",stringValueInt,stringValueLong);  }

程序運行結果

9694ff5a582f749ee38f203857446c6f.png
  • 除了Character類以外,其他所有的包裝類都提供了valueOf()靜態方法用于將字符串轉換為對應的包裝類類型
  /**   * 字符串轉包裝類   */  @Test  public void testStringCastWrapperClass(){    String str="123";    Byte byteRef=Byte.valueOf(str);    Long longRef=Long.valueOf(str);    System.out.printf("byteRef = %d longRef =%d",byteRef,longRef);  }

程序運行結果

4cb93b2b8f953ac8089fcad19bd4e350.png
  • 除了Character以外,其他所有包裝類都提供了parseXX()靜態方法將字符串參數轉換為任意的基本數據類型
 /**   * 字符串轉換為基本數據類型   */  @Test  public void testStringCastPrimitiveType(){    String str="123";    long longValue=Long.parseLong(str);    double doubleValue=Double.parseDouble(str);    byte byteValue=Byte.parseByte(str);    System.out.println("longValue = "+longValue);    System.out.println("doubleValue = "+doubleValue);    System.out.println("byteValue = "+byteValue);    String bool="boolean";    boolean blValue=Boolean.parseBoolean(bool);    System.out.println("blValue = "+blValue);  }

程序運行結果

1bf606b07e4a3f805bebc904d7c82a5e.png

BigInteger類

java.math.BigInteger類表示一個超大的整數,也就是支持任意精度的整數。

當Integer,Long類型的整數不能滿足存儲和計算的要求,此時可以使用字符串的整數構建一個BigInteger對象。

   /**   * BigInteger構造器的使用   */  @Test  public void testBigIntegerConstruct() {    Integer intMax = Integer.MAX_VALUE;    Long longMax = Long.MAX_VALUE;    System.out.printf("int表示的最大值是%d  long 表示的最大值是%d", intMax, longMax);    //此處會編譯錯誤,超過了long的表示范圍    // long value=9223372036854775808L;    BigInteger source=new BigInteger("9223372036854775808");    BigInteger target=new BigInteger("9223372036854775809");    log.info("source = {}  target = {}",source,target);  }

程序運行結果

fc4838e01a3fa76662fafbdce94a465e.png

構造BigInteger對象之后可以使用其提供的方法完成大整數的算術運算

  /**   * 使用BigInteger完成兩個大整數的算術運算   */  @Test  public void testBigIntegerArithmetic(){    BigInteger source=new BigInteger("9223372036854775808");    BigInteger target=new BigInteger("100");    log.info("source = {}  target = {}",source,target);    BigInteger addResult=source.add(target);    log.info("addResult = {}",addResult);    BigInteger subtractResult=source.subtract(target);    log.info("subtractResult = {}",subtractResult);    BigInteger multiplyResult=source.multiply(target);    log.info("multiplyResult = {}",multiplyResult);    BigInteger divideResult=source.divide(target);    log.info("divideResult = {}",divideResult);  }

程序運行結果

c30626c18ce074f07543aea66babc1b8.png

BigDecimal類

浮點數在運算時得到的是一個無限接近結果的近似值,也就是存在精度問題。

    /**     * 浮點數的運算結果是不精確的     *  0.09 + 0.01 = 0.09999999999999999     *  1.0 - 0.32 = 0.6799999999999999     *  1.015 * 100 = 101.49999999999999     *  1.301 / 100 = 0.013009999999999999     */    @Test    public void testFloatPrecision(){        System.out.println("0.09 + 0.01 = "+(0.09 + 0.01 ));        System.out.println("1.0 - 0.32 = "+(1.0-0.32 ));        System.out.println("1.015 * 100 = "+(1.015 * 100 ));        System.out.println("1.301 / 100 = "+(1.301 / 100 ));    }

程序運行結果

b95ce25bb106fbd25840ecd00e278a20.png

BigDecimal類表示任意精度的十進制浮點數,可以解決浮點數運算的精度問題。

     /**     * 使用BigDecimal進行任意精度浮點數的算術運算     */    @Test    public void testBigDecimalArithmetic(){        BigDecimal source=new BigDecimal("0.09");        BigDecimal target=new BigDecimal("0.01");        log.info("source = {}  target = {}",source,target);        BigDecimal addResult=source.add(target);        log.info("addResult = {}",addResult);        source=new BigDecimal("1.0");        target=new BigDecimal("0.32");        log.info("source = {}  target = {}",source,target);        BigDecimal subtractResult=source.subtract(target);        log.info("subtractResult = {}",subtractResult);        source=new BigDecimal("1.015");        target=new BigDecimal("100");        log.info("source = {}  target = {}",source,target);        BigDecimal multiplyResult=source.multiply(target);        log.info("multiplyResult = {}",multiplyResult);        source=new BigDecimal("1.301");        target=new BigDecimal("100");        BigDecimal divideResult=source.divide(target);        log.info("divideResult = {}",divideResult);    }

程序運行結果

1633243e4741dc89cd9fff92f5e20f69.png

但是使用字符串參數的構造器創建BigDecimal對象時在進行除法運算如果除不盡。例如10/3=3.3333 就會拋一個算術異常

/**     * 除法除不盡就會拋異常     */    @Test    public void testBigDecimalDivideMethod(){        BigDecimal source=new BigDecimal("10");        BigDecimal target=new BigDecimal("3");        BigDecimal divideResult=source.divide(target);        System.out.println(divideResult);    }

程序運行結果

efc40969bbf1d293274a18032bad60e5.png

為了解決BigDecimal除法的算術異常(ArithmeticException),可以使用BigDecimal重載的devide()方法。

  /**     * 使用重載的divide方法解決除法除不盡的算術異常     */    @Test    public void testBigDecimalOverrideDivideMethod(){        BigDecimal source=new BigDecimal("10");        BigDecimal target=new BigDecimal("3");        /**         * 重載的divide方法參數說明         * divisor 除數對應的BigDecimal對象         * scale 精確的位數         * roundingMode:取舍模式         */        //計算結果四舍五入 保留2位,        BigDecimal divideResult=source.divide(target,2, RoundingMode.HALF_UP);        log.info("divideResult = {}",divideResult);    }

程序運行結果

adcf7c28b1c26a0424057a409f6b69de.png

在使用BigDecimal是需要注意,不能使用double類型的參數創建BigDecimal對象,其運算的結果也是不精確的

 /**     * 使用浮點數參數的構造器只能獲得更加無限接近的結果,但是還是有精度損失問題     */    @Test    public void testBigDecimalFloatConstruct(){        BigDecimal source= new BigDecimal(0.09);        BigDecimal target= new BigDecimal(0.01);        BigDecimal addResult=source.add(target);        System.out.println("0.09 + 0.01 ="+addResult);    }

程序運行結果

79fc2b5644bcb400ec9312578e6b77cf.png

Arrays類

java.util.Array類是JDK提供的一個工具類,用于數組的常用操作:排序,查找,復制,比較,等等。

906fb7a2f70ebec33f348e5567e06132.png
  • Arrays.sort()方法可以實現數組元素的升序排序,該方法支持八種基本數據類型的數組元素
  /** 數組升序排序 */  @Test  public void testArraySort() {    int[] numbers = {1, 2, 4, 5, 6, 7, 8, 9, 6, 3};    // 將整型數組按照升序排序    Arrays.sort(numbers);    // 將數組以字符串打印在終端    System.out.println(Arrays.toString(numbers));  }

程序運行結果

7b95a4af2fc48a5f2312482e1aaa67a5.png
  • Arrays.binarySearch()方法可以實現數組元素二分法查找,查找之前需要對數組進行排序,該方法支持八種基本數據類型的數組元素
 /** 數組二分法查找 */  @Test  public void testArrayBinarySearch() {    int[] numbers = {1, 2, 4, 5, 6, 7, 8, 9, 6, 3};    // 將整型數組按照升序排序    Arrays.sort(numbers);    // 將數組以字符串打印在終端    System.out.println(Arrays.toString(numbers));    //使用二分法查找指定的數字5,返回5在數組中的索引    int key =5 ;    int index = Arrays.binarySearch(numbers, 5);    System.out.printf("%d在數組中的索引位置是%d",key,index);  }
d0e20cc2c153be8e1d0fa9aed6ff58fb.png

程序運行結果

https://www.zydui.com/afdc8VW8CDQ9TC1UC.html
>

相关文章:

  • PyTorch學習筆記(15) ——PyTorch中的contiguous
  • 英雄聯盟英雄名單部分功能
  • 英雄聯盟皮膚爬蟲
  • java中for循環執行順序
  • for循環執行順序詳解(避坑)
  • DS18B20序列號的讀取
  • 上古卷軸java怎么刷_上古卷軸5快速升級方法一覽 教你如何快速升級
  • 上古卷軸 java_我打通了197KB的《上古卷軸四:湮滅》,諾基亞手機上的那一種...
  • 上古世紀服務器維護,9月22日臨時維護修改會員排隊問題服務器擴容公告
  • 上古世紀服務器維護真情禮,【已開服】4月15日經典服例行維護版本更新公告
  • 上古卷軸ol java_上古卷軸ol怎么滿級快
  • 全網最詳細解釋memcached中的flags含義
  • FLAGS寄存器 標志寄存器 英文全稱 方便記憶
  • Java爬蟲實戰第二篇:IOS、安卓應用爬蟲
  • 什么是storedownloaded,為什么在Mac上運行?
  • CSDN富文本編輯器回車行間距過大問題的解決
  • 批量處理word所有回車行
  • shell判斷字符串變量是否為空,包括純空格、空串、回車行是空白行等
  • 計算機畢業設計之開山車行二手車交易系統
  • Java實現“xx車行管理系統”
  • Java面試案例-車行易
  • 車行管理系統 java小作業
  • 3個躺著賺錢的神仙副業
  • 計算機中的windows任務管理器在哪,Win10系統中的explorer.exe在哪?怎么重啟Windows資源管理器?...
  • Win11查看文件資源管理器選項卡的方法
  • 為什么你總get不到增長玩法背后的邏輯?
  • JDBC連接MySQL數據庫(一)
  • 從零學Java(18)之三元運算符
  • CGU APAC 2017盛大開幕,七彩虹與英偉達聯手打造電競盛宴
  • AP 計算機 華麗逆襲-----被麻省理工計算機博士老師反復勸退的學生逆襲的肺腑之言