<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Java常用類詳解

          共 87582字,需瀏覽 176分鐘

           ·

          2021-05-23 13:23

          點(diǎn)擊上方藍(lán)色字體,選擇“標(biāo)星公眾號(hào)”

          優(yōu)質(zhì)文章,第一時(shí)間送達(dá)

            作者 |  13roky 

          來源 |  urlify.cn/QZfqaa

          1. String類

          1.1 String的特性

          • String類:代表字符串。Java程序中的所有字符串字面值(如“abc”)都作為此類的實(shí)例實(shí)現(xiàn)。

          • String是一個(gè)final類,代表不可變的字符序列

          • String字符串是常量,用雙引號(hào)引起來表示。他們的值在創(chuàng)建之后不能更改。

          • String對(duì)象的找字符內(nèi)容是存儲(chǔ)在一個(gè)字符數(shù)組value[]中的。(jdk新版本已改為使用byte類型的數(shù)組value[]存放)

          1.2 String字面量賦值的內(nèi)存理解

          字面量賦值是直接在常量池中賦值的

          Demo:

          package com.broky.commonClass;

          import org.junit.jupiter.api.Test;

          /**
           * String 的使用
           *
           * @author 13roky
           * @date 2021-04-24 10:34
           */
          public class StringTest {
              /*
                  String:字符串,使用一對(duì)""來表示.
                  1.String類是被聲明為final的,不可被繼承.
                  2.String實(shí)現(xiàn)了Serializable接口:標(biāo)識(shí)字符串是支持序列化的. (io流)
                          實(shí)現(xiàn)了Comparable接口:可以比較大小.
                  3.String內(nèi)部定義了final char[] value用于存儲(chǔ)字符串?dāng)?shù)字. final表示數(shù)組和其元素不能被修改。(為了節(jié)省jvm的內(nèi)存空間jdk9已經(jīng)改為byte[]類型數(shù)組)
                  4.String:代表不可變的字符序列。簡稱:不可變性。
                          體現(xiàn):1.當(dāng)對(duì)字符串重新賦值時(shí),需要重新指定內(nèi)存區(qū)域賦值,不能使用原有的value進(jìn)行賦值.(因?yàn)樵械膙alue是final的)
                              2.當(dāng)對(duì)現(xiàn)有的字符串進(jìn)行連接操作時(shí),需要重新指定內(nèi)存區(qū)域賦值,不能使用原有的value賦值.
                              3.當(dāng)調(diào)用String的replace()方法修改字符或字符串時(shí),也必須重新指定內(nèi)存區(qū)域賦值,不能使用原有的value賦值.
                  5.通過字面量的方式(區(qū)別于new)給一個(gè)字符串賦值,此時(shí)的字符串值生命在字符串常量池中.
                  6.字符串常量池中是不會(huì)存儲(chǔ)相同內(nèi)容的字符串的.
               */
              @Test
              public void test01(){
                  //字面量的定義方式, 在內(nèi)存中用的是同一個(gè)內(nèi)存地址
                  String s1 = "abc";
                  String s2 = "abc";
                  //==比較的是地址值,為true說明s1和s2在內(nèi)存中指向的是同一個(gè)位置
                  System.out.println(s1 == s2);//true
                  
                  s1 = "hello";
                  
                  System.out.println(s1);//hello
                  System.out.println(s2);//abc

                  System.out.println("================================================");

                  String s3 = "abc";
                  s3 += "def";
                  System.out.println(s3);//abcdef
                  System.out.println(s2);//abc

                  System.out.println("================================================");

                  String s4 = "adb";
                  String s5 = s4.replace('a','m');

                  System.out.println(s4);//abc
                  System.out.println(s5);//mbc
              }
          }

          圖解:

          • 由于

            字符串常量池中是不會(huì)存儲(chǔ)相同內(nèi)容的字符串的

            ,所以在字符串常量池中s1和s2指向同一個(gè)內(nèi)存地址。

          • 由于String內(nèi)部定義了final char[] value用于存儲(chǔ)字符串?dāng)?shù)字,final表示數(shù)組和其元素不能被修改,其也就有了

            不可變的字符序列

            的性質(zhì)。所以改變s1取值為hello后,并不會(huì)改變字符串常量池中的對(duì)應(yīng)位置的值,而是會(huì)新開辟一個(gè)內(nèi)存地址存放hello值,并且s1指向新的內(nèi)存地址。

          • 以下圖解類似。

          1.3 String new方式賦值的內(nèi)存理解

          Demo:

          package com.broky.commonClass;

          import org.junit.jupiter.api.Test;

          /**
           * String 的使用
           *
           * @author 13roky
           * @date 2021-04-24 10:34
           */
          public class StringTest {
              /*
              String實(shí)例化方式測試:
              方式一: 通過字面量定義的方式
              方式二: 通過new + 構(gòu)造器的方式

              面試題:String s = new String("abc);方式創(chuàng)建對(duì)象,在內(nèi)存中創(chuàng)建了幾個(gè)對(duì)象?
                      兩個(gè):一個(gè)是堆空間中new結(jié)構(gòu),另一個(gè)是char[]對(duì)應(yīng)的常量池中的數(shù)據(jù)"
          abc"
               */
              @Test
              public void test2() {
                  //通過字面量定義的方式:此時(shí)的s1和s2的數(shù)據(jù)javaEE生命在方法區(qū)中的字符串常量池中.
                  String s1 = "
          javaEE";
                  String s2 = "
          javaEE";
                  //通過new + 構(gòu)造器的方式:此時(shí)的s3和s4保存的地址值是數(shù)據(jù)在堆空間中開辟空間后對(duì)應(yīng)的地址值.
                  String s3 = new String("
          javaEE");
                  String s4 = new String("
          javaEE");

                  System.out.println(s1 == s2);//true
                  System.out.println(s1 == s3);//false
                  System.out.println(s1 == s4);//false
                  System.out.println(s3 == s4);//false
                  System.out.println(s3.equals(s4));//true

                  System.out.println("
          =================================================");

                  Person p1 = new Person("
          Tom",12);
                  Person p2 = new Person("
          Tom",12);

                  System.out.println(p1.name.equals(p2.name));//true
                  System.out.println(p1.name == p2.name);//true
              }
          }

          class Person{
              public String name;
              public int age;

              public Person(String name,int age) {
                  this.name = name;
                  this.age = age;
              }
          }

          圖解:

          new的結(jié)構(gòu)是存在于堆中的,比如 String s3 = new String("javaEE");

          1.4 String 拼接字面量和變量的方式賦值

          Demo:

          package com.broky.commonClass;

          import org.junit.jupiter.api.Test;

          /**
           * String 的使用
           *
           * @author 13roky
           * @date 2021-04-24 10:34
           */
          public class StringTest {
              /*
              1.常量與常量的拼接結(jié)果在常量池。且常量池中不會(huì)存在享同內(nèi)容的常量。
              2.只要其中有一個(gè)是變量,結(jié)果就在堆中。
              3.如果拼接的結(jié)果調(diào)用intern()方法,返回值就會(huì)在常量池中。
               */
              @Test
              public void test03() {
                  String s1 = "javaEE";
                  String s2 = "hadoop";
                  String s3 = "javaEEhadoop";
                  String s4 = "javaEE" + "hadoop";//引號(hào)中的為字面量,這里是字面量的拼接
                  String s5 = s1 + "hadoop";
                  String s6 = "javaEE" + s2;
                  String s7 = s1 + s2;
                  final String s8 = "hadoop";
                  String s9 = "javaEE" + s8;

                  System.out.println(s3 == s4);//true
                  System.out.println(s3 == s5);//false
                  System.out.println(s3 == s6);//false
                  System.out.println(s3 == s7);//false
                  System.out.println(s5 == s6);//false
                  System.out.println(s5 == s7);//false
                  System.out.println(s6 == s7);//false
                  System.out.println(s3 == s9);//true

                  String s10 = s5.intern();//返回值得到的s8使用的常量值中已經(jīng)存在的”javaEEhadoop“(s5.intern返回的時(shí)常量池中對(duì)應(yīng)的內(nèi)存地址)
                  System.out.println(s3 == s10);//true
              }    
          }

          圖解:

          • 常量與常量的拼接,結(jié)果直接保存在常量池中。如String s4 = "javaEE" + "hadoop";,如果常量池中存在“javaEEhadoop”,那么s4直接指向其地址。

          • 只要拼接賦值時(shí),其中有一個(gè)是變量,那么結(jié)果就會(huì)存在于堆中,如String s5 = s1 + "hadoop";,棧中的變量名s5指向堆中對(duì)應(yīng)的地址0x0001,堆中的地址又指向常量池的地址0x1214。

          • s5指向的是堆中的內(nèi)存地址0x0001,但是方法s5.intern返回的直接是常量池中的地址。所以String s10 = s5.intern();這行代碼會(huì)讓s10直接指向常量池對(duì)應(yīng)的內(nèi)存地址。

          package com.broky.commonClass.exer;

          import java.util.Arrays;

          /**
           * @author 13roky
           * @date 2021-04-26 7:27
           */
          public class StringValueChangeEx {
              String str = new String("good");
              char[]  ch = {'t','e','s','t'};

              public void change(String str,char ch[]){
                  str = "test ok";
                  ch[0] = 'b';
              }

              public static void main(String[] args) {
                  StringValueChangeEx test01 = new StringValueChangeEx();
                  test01.change(test01.str, test01.ch);
                  //這里涉及字符串的拼接,所以會(huì)用toString方法,而char中的toString返回的是哈希值,所以要用arrays類
                  System.out.println(test01.str + " and " + Arrays.toString(test01.ch));   //good and [C@2f4d3709
                  System.out.println(test01.str); //good
                  System.out.println(test01.ch);  //test
              }
          }

          1.5 String類常用方法

          1. int Length():返回字符的長度: return value.Length

          2. char charAt(int index):返回某索引處的字return vaLue[index]

          3. booLean isEmpty():判斷是否是空字符牢: return value. Length == 0

          4. String toLowercase():使用默認(rèn)語言環(huán)境,將 String中的所有字符轉(zhuǎn)換為小寫

          5. String toUppercase():使用默認(rèn)語言環(huán)境,將 String中的所有字符轉(zhuǎn)換為大寫

          6. String trim():返回字符的副本,忽略前導(dǎo)空白和尾部空白

          7. boolean equals(Object obj):比較字符的內(nèi)容是否相同

          8. booLean equalsIgnoreCase(String anotherString):與equls方法類似,忽略大小寫

          9. String concat(string str):將指定字符牢連接到此字符的結(jié)尾。等價(jià)于用"+"

          10. int compare To(String anotherstring):比較兩個(gè)字符的大小

          11. String substring(int beginIndex):返回一個(gè)新的字符,它是此字符的從 beginIndex開始截取到最后一個(gè)子字符串.

          12. String substring(int beginIndex, int endindex):返回一個(gè)新字符串,它是此字符從beginIndex開始截取到endIndex(不包含)的一個(gè)子字符串.

          Demo:

          package com.broky.commonClass;

          import org.junit.jupiter.api.Test;

          import java.util.Locale;

          /**
           * @author 13roky
           * @date 2021-04-26 21:47
           */
          public class CommonMethod {
              /*
              int Length():返回字符的長度: return value.Length
              char charAt( nt index):返回某索引處的字return vaLue[index]
              booLean isEmpty():判斷是否是空字符牢: return value. Length == 0
              String toLowercase():使用默認(rèn)語言環(huán)境,將 String中的所有字符轉(zhuǎn)換為小寫
              String toUppercase():使用默認(rèn)語言環(huán)境,將 String中的所有字符轉(zhuǎn)換為大寫
              String trim():返園字符的副本,忽略前導(dǎo)空白和尾部空白
              boolean equals(Object obj):比較字符的內(nèi)容是否相同
              booLean equalsIgnoreCase(String anotherString):與equls方法類似,忽略大小寫
              String concat(string str):將指定字符牢連接到此字符的結(jié)尾。等價(jià)于用"+"
              int compare To(String anotherstring):比較兩個(gè)字符的大小
              String substring(int beginIndex):返回一個(gè)新的字符,它是此字符的從 beginIndex開始截取到最后一個(gè)子字符串.
              String substring(int beginIndex, int endindex):返回一個(gè)新字符串,它是此字符從beginIndex開始截取到endIndex(不包含)的一個(gè)子字符串.
               */
              @Test
              public void test01(){
                  String s1 ="HelloWorld";
                  System.out.println(s1.length());
                  System.out.println(s1.charAt(0));
                  System.out.println(s1.charAt(9));
                  System.out.println(s1.isEmpty());

                  String s2 = s1.toLowerCase();
                  System.out.println(s1);
                  System.out.println(s2);

                  String s3 = "    he  llo    world    ";
                  String s4 = s3.trim();
                  System.out.println(s3);
                  System.out.println(s4);
              }

              @Test
              public void test02(){
                  String s1 = "HelloWorld";
                  String s2 = "helloworld";
                  System.out.println(s1.equals(s2));
                  System.out.println(s1.equalsIgnoreCase(s2));

                  String s3 = "abc";
                  String s4 = "def".concat(s3);
                  System.out.println(s4);

                  String s5 = "abc";
                  String s6 = new String("abd");
                  System.out.println(s5.compareTo(s6));

                  String s7 = "13roky學(xué)Java";
                  String s8 = s7.substring(2,6);
                  System.out.println(s7);
                  System.out.println(s8);
              }
          }
          1. boolean endsWith(String suffix):測試此字符串是否以指定的后綴結(jié)束

          2. boolean startsWith(String prefix):測試此字符串是否以指定的前綴開始

          3. boolean startsWith(String prefix, int toffset):測試此字符串從指定索引開始的子字符串是否以指定的前綴開始

          4. boolean contains(CharSequence s):當(dāng)且僅當(dāng)此字符串包含指定的char值序列時(shí),返回true

          5. int indexOf(String str): 返回指定子字符串在此字符串中第一次出現(xiàn)處的索引

          6. int indexOf(String str,int fromIndex):返回指定子字符串在此字符串中第一次出現(xiàn)處的索引,從指定的索引處開始

          7. int lastIndexOf(String str):返回指定子字符串在此字符串中最右邊出現(xiàn)處的索引

          8. int lastIndexOf(String str,int fromIndex):返回指定子字符串在此字符串中最后一次出現(xiàn)處的索引,從指定的索引開始反向搜索(從右往左搜索)indexOf和lastindexOf方法如果未找到,返回結(jié)果都是-1

          Demo:

          package com.broky.commonClass;

          import jdk.jfr.DataAmount;
          import org.junit.jupiter.api.Test;

          import java.util.Locale;

          /**
           * @author 13roky
           * @date 2021-04-26 21:47
           */
          public class CommonMethod {
              /*
              boolean endsWith(String suffix):測試此字符串是否以指定的后綴結(jié)束
              boolean startsWith(String prefix):測試此字符串是否以指定的前綴開始
              boolean startsWith(String prefix, int toffset):測試此字符串從指定索引開始的子字符串是否以指定的前綴開始

              boolean contains(CharSequence s):當(dāng)且僅當(dāng)此字符串包含指定的char值序列時(shí),返回true
              int indexOf(String str): 返回指定子字符串在此字符串中第一次出現(xiàn)處的索引
              int indexOf(String str,int fromIndex):返回指定子字符串在此字符串中第一次出現(xiàn)處的索引,從指定的索引處開始
              int lastIndexOf(String str):返回指定子字符串在此字符串中最右邊出現(xiàn)處的索引
              int lastIndexOf(String str,int fromIndex):返回指定子字符串在此字符串中最后一次出現(xiàn)處的索引,從指定的索引開始反向搜索(從右往左搜索)
              indexOf和lastindexOf方法如果未找到,返回結(jié)果都是-1
              */
              @Test
              public void test03(){
                  String str1 = "helloworld";
                  boolean b1 = str1.endsWith("rld");
                  System.out.println(b1);

                  boolean b2 = str1.startsWith("He");
                  System.out.println(b2);

                  boolean b3 =str1.startsWith("ll",2);
                  System.out.println(b3);

                  String str2 = "wo";
                  System.out.println(str1.contains(str2));

                  System.out.println(str1.indexOf("lol"));
                  System.out.println(str1.indexOf("l"));
                  System.out.println(str1.indexOf("lo", 5));

                  String str3 = "hellorworld";
                  System.out.println(str3.lastIndexOf("or"));
                  System.out.println(str3.lastIndexOf("or",6));
              }
              //什么情況下,indexOf(str)和lastIndexOf(str)返回值相同?
              //情況一:存在唯一的一個(gè)str.
              //情況二:不存在str
          }
          1. 替換:
            String replace(char oldChar,char newChar):返回一個(gè)新的字符串,它是通過用newChar替換oldChar
            String replace(CharSequence target,CharSequence replacement):使用字面值替換序列替換此字符串所有匹配字面值目標(biāo)序列的子字符串.
            String replaceAll(String regex,String replacement):使用給定的replacement替換此字符串多有匹配給定的正則表達(dá)式的子字符串
            String replaceFirst(String regex,String replacement):使用給定的replacement替換此字符串匹配給定的正則表達(dá)式的第一個(gè)子字符串.

          2. 匹配:
            boolean matches(String regex):告知此字符串是否匹配給定得正則表達(dá)式

          3. 切片:
            String[] split(String regex):根據(jù)給定的正則表達(dá)式的匹配拆分此字符串
            String[] split(String regex,int limit):根據(jù)匹配給定的正則表達(dá)式來分此字符串,最多不超過limit個(gè),如果超出,剩下的全部都放到最后一個(gè)元素

          Demo:

          package com.broky.commonClass;

          import jdk.jfr.DataAmount;
          import org.junit.jupiter.api.Test;

          import java.util.Locale;

          /**
           * @author 13roky
           * @date 2021-04-26 21:47
           */
          public class CommonMethod {
              /*
              替換
              String replace(char oldChar,char newChar):返回一個(gè)新的字符串,它是通過用newChar替換oldChar
              String replace(CharSequence target,CharSequence replacement):使用字面值替換序列替換此字符串所有匹配字面值目標(biāo)序列的子字符串.
              String replaceAll(String regex,String replacement):使用給定的replacement替換此字符串多有匹配給定的正則表達(dá)式的子字符串
              String replaceFirst(String regex,String replacement):使用給定的replacement替換此字符串匹配給定的正則表達(dá)式的第一個(gè)子字符串.
              匹配:
              boolean matches(String regex):告知此字符串是否匹配給定得正則表達(dá)式
              切片:
              String[] split(String regex):根據(jù)給定的正則表達(dá)式的匹配拆分此字符串
              String[] split(String regex,int limit):根據(jù)匹配給定的正則表達(dá)式來分此字符串,最多不超過limit個(gè),如果超出,剩下的全部都放到最后一個(gè)元素
               */
              @Test
              public void test04(){
                  String str1 = "13roky學(xué)Java";
                  String str2 = str1.replace('學(xué)','寫');

                  System.out.println(str1);
                  System.out.println(str2);

                  String str3 = str1.replace("13roky""geek");
                  System.out.println(str3);

                  System.out.println("=====================================================");
                  String str = "123klnjklsdnafdmc123pojasvapos";
                  String string = str.replace("\\d+",",").replaceAll("^,|,$","|");
                  System.out.println(string);

                  str = "12345";
                  //判斷str字符串中是否全部有數(shù)字組成,即有1-n個(gè)數(shù)字組成
                  boolean matches = str.matches("\\d+");
                  System.out.println(matches);
                  String tel = "0571-4534289";
                  //判斷一個(gè)電話是否是杭州的
                  boolean result = tel.matches("0571-\\d{7,8}");
                  System.out.println(result);

                  System.out.println("================================================");
                  str = "hello|world|java";
                  String[] strs = str.split("\\|");

                  for (int i = 0; i < strs.length; i++) {
                      System.out.println(strs[i]);
                  }
                  System.out.println();
                  str2 = "hello.world.java";
                  String[] strs2 = str2.split("\\|");
                  for (int i = 0; i < strs2.length; i++) {
                      System.out.println(strs2[i]);
                  }
              }
          }

          1.6 String與其它類型的轉(zhuǎn)換

          demo:

          package com.broky.commonClass;

          import org.junit.jupiter.api.Test;

          import java.io.UnsupportedEncodingException;
          import java.util.Arrays;

          /**
           * String類與其他結(jié)構(gòu)之間的轉(zhuǎn)換
           * String 與 char[] 之間的轉(zhuǎn)換
           * String 與 byte[] 之間的轉(zhuǎn)換
           *
           * @author 13roky
           * @date 2021-05-02 19:33
           */
          public class StringChange {
              /*
              復(fù)習(xí):String與其他數(shù)據(jù)類型,包裝類之間的轉(zhuǎn)換
              String --> 基本數(shù)據(jù)類型、包裝類:調(diào)用包裝類的靜態(tài)方法:parseXxx(str)
              基本數(shù)據(jù)類型、包裝類 ——》String:調(diào)用String重載的valueOf(xxx) 或者直接拼接“”
               */
              @Test
              public void test(){
                  String str = "123";
                  //int num = (int) str;   只有子父類的關(guān)系才可以使用強(qiáng)制類型轉(zhuǎn)換

                  int num = Integer.parseInt(str);

                  String str2 = String.valueOf(num);
                  String str3 = num + "";
              }

              /*
              String 與 char[] 之間的轉(zhuǎn)換

              String --> char[] :String類中的toCharArray()方法
              char[] --> String :String的構(gòu)造器
               */
              @Test
              public void test02(){
                  String str = "abcde";

                  char[] c1 = str.toCharArray();

                  for (int i = 0; i < c1.length; i++) {
                      System.out.println(c1[i]);
                  }

                  char[] c2 = new char[]{'f','s','c','a'};

                  String str2 = new String(c2);
                  System.out.println(str2);
              }

              /*
              String 與 byte[] 之間的轉(zhuǎn)換
              編碼:String --> byte[] :調(diào)用String的getBytes()
              解碼:

              轉(zhuǎn)化的時(shí)候會(huì)涉及編碼和解碼
              編碼:字符串 --> 字節(jié) (看得懂轉(zhuǎn)換為看不懂的二進(jìn)制數(shù)據(jù))
              解碼 字節(jié) --> 字符串 (看不懂的二進(jìn)制數(shù)據(jù)轉(zhuǎn)換為看得懂)

               */
              @Test
              public void test03() throws UnsupportedEncodingException {
                  String str = "abc123此方";
                  // 使用ide默認(rèn)的編碼集進(jìn)行轉(zhuǎn)換
                  byte[]  b1 = str.getBytes();
                  // 字節(jié)byte類型 采用ASCLL編碼 由于ASCLL中沒有中文編碼,所以中文會(huì)轉(zhuǎn)為默認(rèn)的編碼如(UTF-8,UTF-8中一個(gè)漢字占三位)然后再轉(zhuǎn)為ASCLL
                  System.out.println(Arrays.toString(b1));
                  // 使用 gbk 字符集進(jìn)行編碼,需要處理異常
                  byte[] b2 = str.getBytes("gbk");

                  System.out.println(Arrays.toString(b2));
                  System.out.println("=======================================");
                  // 使用ide默認(rèn)的編碼集進(jìn)行解碼
                  String str2 = new String(b1);
                  System.out.println(str2);
                  // 出現(xiàn)亂碼。原因:編碼及和解碼集不一致倒置的
                  String str3 = new String(b2);
                  System.out.println(str3);

                  // 指定編碼集
                  String str4 = new String(b2, "gbk");
                  System.out.println(str4);
              }
          }

          1.7 常見算法題目

          1. 模擬一個(gè)trim方法,去除字符串兩端的空格。

          2. 將一個(gè)字符串進(jìn)行反轉(zhuǎn)。將字符串中間指定部分進(jìn)行反轉(zhuǎn)。比如“abcdefg”反轉(zhuǎn)為“abfedcg”。

          3. 獲取一個(gè)字符串在另一個(gè)字符串中出現(xiàn)的次數(shù)。

          4. 獲取兩個(gè)字符串中最大的相同字符串。

          5. 將字符串中字符進(jìn)行自然順序排序。Arrays.sort()

          package com.broky.commonClass.exer;import org.junit.jupiter.api.Test;import java.nio.CharBuffer;import java.util.Arrays;import java.util.Objects;/** * 四道常見String算法題目 * 1. 模擬一個(gè) trim 方法,去除字符串兩端的空格。 * * @author 13roky * @date 2021-05-08 10:06 */public class Algorithms {    @Test    public void testMyTrim() {        String s1 = "   123   ";        s1.trim();        s1 = myTrim(s1);        System.out.println(s1);    }    // 模擬一個(gè) trim 方法,去除字符串兩端的空格。    public String myTrim(String str) {        if (str != null) {            int start = 0;// 用于記錄從前往后首次索引位置不是空格的位置的索引            int end = str.length() - 1;// 用于記錄從后往前首次索引位置不是空格的位置的索引            while (start < end && str.charAt(start) == ' ') {                start++;            }            while (start < end && str.charAt(end) == ' ') {                end--;            }            if (str.charAt(start) == ' ') {                return "";            }            return str.substring(start, end + 1);        }        return null;    }    @Test    public void testMyReverse() {        System.out.println(myReverse01("abcdefg", 2, 5));        System.out.println(myReverse02("abcdefg", 2, 5));        System.out.println(myReverse03("abcdefg", 2, 5));    }    /*    將一個(gè)字符串進(jìn)行反轉(zhuǎn)。將字符串中指定部分進(jìn)行反轉(zhuǎn)。比如“abcdefg”反轉(zhuǎn)為“abfedcg”     */    // 方式一:轉(zhuǎn)換為char[]    public String myReverse01(String str, int start, int end) {        if (str != null) {            char[] chars = str.toCharArray();            char tmp = 0;            for (int s = start, e = end; s < e; s++, e--) {                tmp = chars[s];                chars[s] = chars[e];                chars[e] = tmp;            }            return new String(chars);        }        return null;    }    // 方式二:使用String的拼接    public String myReverse02(String str, int start, int end) {        if (str != null) {            String partOne = str.substring(0, start);            String parThree = str.substring(end + 1);            for (int i = end; i >= start; i--) {                partOne += str.charAt(i);            }            partOne += parThree;            return partOne;        }        return null;    }    // 方式三:使用StringBuffer 或 StringBuilder 替換String    public String myReverse03(String str, int start, int end) {        StringBuilder builder = new StringBuilder(str.length());        builder.append(str.substring(0, start));        for (int i = end; i >= start; i--) {            builder.append(str.charAt(i));        }        builder.append(str.substring(end + 1));        return String.valueOf(builder);    }    /*    獲取一個(gè)字符串在另一個(gè)字符串中出現(xiàn)的次數(shù)。    如:獲取 "ab" 在 “abkkcakabkebfkabkskab” 出現(xiàn)的次數(shù)     */    @Test    public void testGetCount() {        getCount01("ab""abkkcakabkebfkabkskab");        getCount02("ab""abkkcakabkebfkabkskab");    }    // 方法一:    public int getCount01(String mainStr, String subStr) {        int n = 0;        for (int i = 0; i < subStr.length() - mainStr.length() + 1; i++) {            if (mainStr.charAt(0) == subStr.charAt(i)) {                if (mainStr.equals(subStr.substring(i, i + mainStr.length()))) {                    n++;                }            }        }        System.out.println(n);        return n;    }    // 方法二:    public int getCount02(String mainStr, String subStr) {        int count = 0;        int index = 0;        if (subStr.length() >= mainStr.length()) {//            while ((index = subStr.indexOf(mainStr)) != -1) {//                count++;//                subStr = subStr.substring(index + mainStr.length());//            }            // 改進(jìn)            while ((index = subStr.indexOf(mainStr,index)) != -1) {                count++;                index += mainStr.length();            }            System.out.println(count);            return count;        } else {            return 0;        }    }}

          2. StringBuffer 和 StringBuilder類

          2.1 String、StringBuffer、StringBuilder 三者的異同

          • String:不可變的字符序列,底層使用char[]進(jìn)行存儲(chǔ)

          • StringBuffer:可變的字符序列,線程安全的,效率低,底層使用char[]進(jìn)行存儲(chǔ)

          • StringBuilder:可變的字符序列,線程不安全的,效率高,jdk5.0新特性,底層使用char[]進(jìn)行存儲(chǔ)

          源碼分析

          • String:
            String str = new String(); // 底層代碼為 char[] value = new char[0];
            String str1 = new String("abc"); // 底層代碼為 char[] value = new char[]{'a','b','c'};

          • StringBuffer:
            String sb1 = new StringBuffer(); // char[] value = new char[16];底層創(chuàng)建了一個(gè)長度是16的數(shù)組
            sb1.append('a'); // value[0] = 'a';
            sb1.append('b'); // value[1] = 'b';

          • 問題:

            1. System.out.println(sb1.length()); 返回的是有的值count,而不是底層開辟的空間value.length.

            2. 擴(kuò)容問題,如果要添加的數(shù)據(jù)底層數(shù)組盛不下了,那就需要擴(kuò)容底層的數(shù)組。默認(rèn)情況下,擴(kuò)容為原來容量的2倍+2(源碼中采用了位運(yùn)算<<),同時(shí)將原有數(shù)組中的元素復(fù)制到新數(shù)組中。

          • 總結(jié):

            1. 開發(fā)中盡量不要用String,String不可變,效率最差,每次都會(huì)新造。而StringBuufer和StringBuilder只有長度不夠用的時(shí)候才去擴(kuò)容并復(fù)制。

            2. 開發(fā)中如果知道會(huì)頻繁使用append時(shí),建議使用StringBuffer的指定容量的構(gòu)造器,避免之后進(jìn)行擴(kuò)容。

          2.2 StringBuffer 類的常用方法

          • StringBuffer append(xx):提供了很多的 append()方法,用于進(jìn)行字符拼接

          • StringBuffer delete( int start, int end):刪除指定位置的內(nèi)容,本身發(fā)生改變,并返回值。

          • StringBuffer replace( int start, int end, String str):把 start,end)位置替換為str

          • StringBuffer insert( int offset,xxx):在指定位置插入xxx

          • StringBuffer reverse():把當(dāng)前字符序列逆轉(zhuǎn)

          • public int indexof(string str)

          • pubLic String substring (int start, int end) 返回一個(gè)從Start開始到End結(jié)束的左閉右開區(qū)間的子字符串,本身值并未變化

          • public int Length

          • public char charAt(int n)

          • public void setcharAt (int n, char ch)

          • 總結(jié):
            增:append(xx)
            刪:delete( int start, int end)
            改:setCharAt(int n,char ch) / replace( int start, int end, String str)
            查:charAt(int n)
            插:insert( int offset,xxx)
            長度:Length()
            遍歷:for() + charAt() / toString()

          • 方法鏈的原理:s1.append().append().append(); s1調(diào)用完append后返回的依舊是s1,可以繼續(xù)調(diào)用append

          package com.broky.commonClass.exer;import org.junit.jupiter.api.Test;/** * StringBuffer 的常用方法 * * @author 13roky * @date 2021-05-07 13:27 */public class StringBufferMethod {    @Test    public void test(){        StringBuffer s1 = new StringBuffer("abc");        s1.append(1);        s1.append("234");        System.out.println(s1.delete(2, 4));        System.out.println(s1);        System.out.println(s1.replace(2, 4, "hello"));        System.out.println(s1.reverse());    }}

          關(guān)于append方法

          package com.broky.commonClass;import org.junit.jupiter.api.Test;public class StringBufferBuilderTest {       @Test    public void test2(){        String str = null;        StringBuffer sb = new StringBuffer();        //StringBuffer 的 append 方法會(huì)將null值轉(zhuǎn)換為字符“null”加入        sb.append(str);        System.out.println(sb.length());//4        System.out.println(sb);//"null"        StringBuffer sb2 = new StringBuffer(str);        System.out.println(sb2);    }}

          2.3 String、StringBuffer、StringBuilder 三者的效率

          效率:StringBuilder > StringBuffer > String

          package com.broky.commonClass;import org.junit.jupiter.api.Test;    /**     * String StringBuffer StringBuilder 效率測試     */    @Test    public void timeTest() {        long startTime = 0L;        long endTime = 0L;        String text = "";        StringBuffer buffer = new StringBuffer("");        StringBuilder builder = new StringBuilder("");        startTime = System.currentTimeMillis();        for (int i = 0; i < 20000; i++) {            buffer.append(String.valueOf(i));        }        endTime = System.currentTimeMillis();        System.out.println("StringBuffer 執(zhí)行時(shí)間" + (endTime - startTime));        startTime = System.currentTimeMillis();        for (int i = 0; i < 20000; i++) {            builder.append(String.valueOf(i));        }        endTime = System.currentTimeMillis();        System.out.println("StringBuilder 執(zhí)行時(shí)間" + (endTime - startTime));        startTime = System.currentTimeMillis();        for (int i = 0; i < 20000; i++) {            text = text + String.valueOf(i);        }        endTime = System.currentTimeMillis();        System.out.println("String 執(zhí)行時(shí)間" + (endTime - startTime));    }}

          3. JDK8 之前的日期和時(shí)間 api 相關(guān)類

          3.1 java.lang.System 類

          System 類提供的 public static long currentTimeMillis() 用來返回當(dāng)前時(shí)間與1970年1月1日0時(shí)0分0秒之間以毫秒為單位的時(shí)間差。

          3.2 java.util.Date 和 java.sql.Date 類

          1. 兩個(gè)構(gòu)造器的使用

            構(gòu)造器一:Date():創(chuàng)建一個(gè)對(duì)應(yīng)當(dāng)前時(shí)間的Date對(duì)象
            構(gòu)造器二:創(chuàng)建指定毫秒數(shù)的Date對(duì)象

          2. 兩個(gè)方法的使用

            toString():顯示當(dāng)前的年、月、日、時(shí)、分、秒
            getTime():獲取當(dāng)前Date對(duì)象對(duì)應(yīng)的毫秒數(shù)。(時(shí)間戳)

          3. java.sql.Date 對(duì)應(yīng)這數(shù)據(jù)庫中的日期類型的變量

            實(shí)例化
            將 sql.date 轉(zhuǎn)換 util.date: 多態(tài)直接賦值
            將 util.date 轉(zhuǎn)換 sql.date: 通過共同的getTime()時(shí)間戳實(shí)現(xiàn)

          Demo:

          package com.broky.commonClass;import org.junit.jupiter.api.Test;import java.util.Date;/** *  JDK8 之前的日期和時(shí)間的 api 測試 * * @author 13roky * @date 2021-05-08 9:15 */public class DateTimeTest {    /*    System類提供的 public static long currentTimeMillis()    用來返回當(dāng)前時(shí)間與1970年1月1日0時(shí)0分0秒之間以毫秒為單位的時(shí)間差。     */    @Test    public void test() {        long time = System.currentTimeMillis();        System.out.println(time);    }    /*    java.util.Date 類            |---java.sql.Date 類 數(shù)據(jù)庫    1. 兩個(gè)構(gòu)造器的使用        > 構(gòu)造器一:Date():創(chuàng)建一個(gè)對(duì)應(yīng)當(dāng)前時(shí)間的Date對(duì)象        > 構(gòu)造器二:創(chuàng)建指定毫秒數(shù)的Date對(duì)象    2. 兩個(gè)方法的使用        > toString():顯示當(dāng)前的年、月、日、時(shí)、分、秒        > getTime():獲取當(dāng)前Date對(duì)象對(duì)應(yīng)的毫秒數(shù)。(時(shí)間戳)    3. java.sql.Date 對(duì)應(yīng)這數(shù)據(jù)庫中的日期類型的變量        > 實(shí)例化        > 將 sql.date 轉(zhuǎn)換 util.date: 多態(tài)直接賦值        > 將 util.date 轉(zhuǎn)換 sql.date: 通過共同的getTime()時(shí)間戳實(shí)現(xiàn)     */    @Test    public void test02() {        // 構(gòu)造器一:Date():創(chuàng)建一個(gè)對(duì)應(yīng)當(dāng)前時(shí)間的Date對(duì)象        Date date1 = new Date();        System.out.println(date1.toString());        System.out.println(date1.getTime());        // 構(gòu)造器二:創(chuàng)建指定毫秒數(shù)的Date對(duì)象        Date date2 = new Date(1620437519431L);        java.sql.Date date3 = new java.sql.Date(1620437519431L);        System.out.println(date3);        // 將 util.date 轉(zhuǎn)換 sql.date:        // 情況一        Date date4 = new java.sql.Date(1620437519431L);        java.sql.Date date5 = (java.sql.Date) date4;        // 情況二        Date date6 = new Date();        java.sql.Date date7 = new java.sql.Date(date6.getTime());        /*        當(dāng)new的是父類的時(shí)候,如果強(qiáng)轉(zhuǎn)為子類,那么編譯時(shí)不會(huì)報(bào)錯(cuò),運(yùn)行時(shí)會(huì)報(bào)錯(cuò),因?yàn)閚ew的父類缺少子類特有的屬性和方法        當(dāng)new的是子類的時(shí)候,但是賦給了父類,這時(shí)候是可以強(qiáng)轉(zhuǎn)成子類的,如情況一         */    }}

          注意:

          使用Data的構(gòu)造器,設(shè)置時(shí)間會(huì)存在 偏移量 的問題

          Demo:

          package com.broky.commonClass;import org.junit.jupiter.api.Test;import java.util.Date;/** * JDK8 之前的日期和時(shí)間的 api 測試 * * @author 13roky * @date 2021-05-08 9:15 */public class DateTimeTest {    // Date中的偏移量    @Test    public void test01() {        /*        由于構(gòu)造方法存在一個(gè)偏移量,年份是從1990年開始,月份是從0開始所以構(gòu)造時(shí)應(yīng)該減去偏移量         */        Date date1 = new Date(2020, 9, 8);        System.out.println(date1);  // Fri Oct 08 00:00:00 CST 3920        date1 = new Date(2020 - 1900, 9 - 1, 8);        System.out.println(date1);  // Tue Sep 08 00:00:00 CST 2020    }}

          3.3 SimpleDateFormat 類

          SimpleDateFormat 是用來 格式化 Date 類中 時(shí)間格式的 和 對(duì)格式進(jìn)行解析成 Date 的類

          可以使用默認(rèn)格式,也可以自定義格式。

          1. 兩個(gè)操作
            1.1 格式化:日期 ---> 字符串
            1.2 解析:格式化的逆過程,字符串 ---> 日期

          2. SimpleDateFormat 的實(shí)例化

          Demo

          package com.broky.commonClass;import org.junit.jupiter.api.Test;import java.text.ParseException;import java.text.SimpleDateFormat;import java.util.Date;/** * jdk 8 之前的日期時(shí)間的API測試 * 1. System類中currentTimeMillis(); * 2. java.util.Date 和 子類 java.sql.Date * 3. SimpleDateFormat * 4. Calendar * * @author 13roky * @date 2021-05-09 12:53 */public class DateTimeTest2 {    /*    SimpleDateFormat 的使用:SimpleDateFormat對(duì)日期 Date 類的格式化和解析    1. 兩個(gè)操作    1.1 格式化:日期 ---> 字符串    1.2 解析:格式化的逆過程,字符串 ---> 日期    2. SimpleDateFormat 的實(shí)例化     */    @Test    public void testSimpleDateFormat() throws ParseException {        // 實(shí)例化SimpleDateFormat:使用默認(rèn)的構(gòu)造器        SimpleDateFormat sdf = new SimpleDateFormat();        // 格式化:日期 ---> 字符串        Date date = new Date();        System.out.println(date);        String format = sdf.format(date);        System.out.println(format);        // 解析: 格式化的逆過程,字符串 ---> 日期        String str = "2021/5/9 下午1:04";        Date date1 = null;        date1 = sdf.parse(str);        System.out.println(date1);        //*********************************        // SimpleDateFormat sdf1 = new SimpleDateFormat("yyyyy.MMMMM.dd GGG hh:mm aaa");        SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");        String format1 = sdf1.format(date);        System.out.println(format1);        Date date2 = sdf1.parse("2021-05-09 01:09:56");        System.out.println(date2);    }}

          練習(xí):

          1. 字符串“2020-02-23”轉(zhuǎn)化為java.sql.Date

          2. 三天打魚兩天曬網(wǎng) 1990-01-01 視頻分析:P482480.尚硅谷_常用類-SimpleDateFormat的課后練習(xí)2

          package com.broky.commonClass;import org.junit.jupiter.api.Test;import java.text.ParseException;import java.text.SimpleDateFormat;import java.util.Date;    @Test    public void testEx01() throws ParseException {        //練習(xí)一:字符串“2020-02-23”轉(zhuǎn)化為java.sql.Date        String str ="2020-02-23";        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");        Date date = sdf.parse(str);        System.out.println(date);        java.sql.Date sqlDate = new java.sql.Date(date.getTime());        System.out.println(sqlDate);    }    @Test    public void testEx02() throws ParseException {        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");        Date startDate = sdf.parse("1990-01-01");        long oneDay = sdf.parse("1990-01-02").getTime() - startDate.getTime();        long period = oneDay * 5;        //        long now = sdf.parse(sdf.format(new Date())).getTime() - startDate.getTime();        long now = sdf.parse("1990-01-06").getTime() - startDate.getTime() + oneDay;        if (now % period > 3 * oneDay || now % period == 0) {            System.out.println("曬網(wǎng)");        } else {            System.out.println("打魚");        }    }}

          3.4 Calendar 類

          • calendar類是一個(gè)抽象類,是可變的

          demo

          package com.broky.commonClass;import org.junit.jupiter.api.Test;import java.text.ParseException;import java.text.SimpleDateFormat;import java.util.Calendar;import java.util.Date;/** * jdk 8 之前的日期時(shí)間的API測試 * 1. System類中currentTimeMillis(); * 2. java.util.Date 和 子類 java.sql.Date * 3. SimpleDateFormat * 4. Calendar * * @author 13roky * @date 2021-05-09 12:53 */public class DateTimeTest2 {         /*        Calendar 日歷類(抽象類)的使用     */    @Test    public void testCalendar(){        // 1. 實(shí)例化        // 方式一: 創(chuàng)建其子類 (GregorianCalendar)的對(duì)象        // 方式二:調(diào)用其靜態(tài)方法getInstance()        // 兩種創(chuàng)建方法本質(zhì)上一樣        Calendar calendar = Calendar.getInstance();        System.out.println(calendar.getClass());        // 2.常用方法        //get()        int days = calendar.get(Calendar.DAY_OF_MONTH);        System.out.println(days);        //set()        calendar.set(Calendar.DAY_OF_MONTH,22);        days = calendar.get(Calendar.DAY_OF_MONTH);        System.out.println(days);        //add()        calendar.add(Calendar.DAY_OF_MONTH,-3);        days = calendar.get(Calendar.DAY_OF_MONTH);        System.out.println(days);        //getTime(): 日歷類-->Date        Date date = calendar.getTime();        System.out.println(date);        //setTime(): Date--->日歷類        Date date1 = new Date();        calendar.setTime(date1);        days = calendar.get(Calendar.DAY_OF_MONTH);        System.out.println(days);    }}

          注意

          • 獲取月份時(shí):一月是0,二月是1,以此類推12月是11

          • 獲取星期時(shí):周日是1,周二是2.。。。周六是7

          3.5 JDK8 之前時(shí)間日期api的一些問題

          如果我們可以跟別人說:“我們在1502643933071見晚了!”那么就再簡單不過了。但是我們希望時(shí)間與量夜和四季有關(guān),于是事情就變復(fù)雜了。JDK10中包含了個(gè) java util. Date類,但是它的大多數(shù)方法已經(jīng)在JDK11引入 Calendar類之后被棄用而 Calendar并不比Date好多少。它們面臨的問題是:

          **可變性: **像日期和時(shí)間這樣的類應(yīng)該是不可變的。

          **偏移性: **Date中的年份是從1900開始的,而月份都從0開始。

          格式化: 格式化只對(duì)Date有用, Calendar則不行

          此外,它們也不是線程安全的;不能處理閏秒等。

          因此我們需要引入 以下 新的時(shí)間日期api來處理這些問題

          4. JDK8 中新的時(shí)間日期 api

          • 第三次引入的API是成功的,并且Java8中引入的 java. time API 已經(jīng)糾正了過去的缺陷,將來很長一段時(shí)間內(nèi)它都會(huì)為我們服務(wù)。

          • Java8 吸收了Joda-Time的精華,以一個(gè)新的開始為Java創(chuàng)建優(yōu)秀的AP新的 java. time中包含了所有關(guān)于本地日期( LocalDate)本地時(shí)間( LocalTime)本地日期時(shí)間( LocalDate Time)時(shí)區(qū)( Zoned Date Time)持續(xù)時(shí)間( Duration)的類。歷史悠久的Date類新增了 tolnstant()方法,用于把Date轉(zhuǎn)換成新的表示形式。這些新增的本地化時(shí)間口期 API 大大簡化了日期時(shí)間和本地化的管理。

          • 在JDK8 之前joda-time是作為jar包的形式導(dǎo)入項(xiàng)目使用的,在jdk8 的時(shí)候官方將其引入.

          4.1 LocalDate、LocalTime、LocalDateTime 類的使用

          實(shí)例化:

          • 實(shí)例化方式一:使用靜態(tài)方法 now() / now(zoneld zone) 獲取當(dāng)前的日期時(shí)間

          • 實(shí)例化方式二:使用靜態(tài)方法 of()自定義時(shí)間,無 Date 中偏移量的問題

          方法 :

          • now() / now(zoneld zone)

          • of()

          • getXxx() 獲取相關(guān)屬性

          • withXxxx() 設(shè)置相關(guān)屬性

          • plusXxx() 在現(xiàn)有基礎(chǔ)上加上指定數(shù)據(jù)

          • minusXxx() 在現(xiàn)有基礎(chǔ)上減去指定數(shù)據(jù)

          說明 :

          • 三個(gè)類都具有不可變性

          • LocalDateTime 相較于 LocalDate , LocalTime 使用頻率更高

          • 類似于 jdk8 之前的 Calendar 類

          Demo:

          package com.broky.commonClass;import org.junit.jupiter.api.Test;import java.time.LocalDate;import java.time.LocalDateTime;import java.time.LocalTime;/** * jdk 8 中的時(shí)間日期 api * * @author 13roky * @date 2021-05-10 7:05 */public class JDK8DateTimeTest {    /*    LocalDate、LocalTime、LocalDateTime 類的使用:     */    @Test    public void test01(){        // 實(shí)例化方式一:使用靜態(tài)方法 now() / now(zoneld zone) 獲取當(dāng)前的日期時(shí)間        LocalDateTime localDateTime = LocalDateTime.now();        LocalDate localDate = LocalDate.now();        LocalTime localTime = LocalTime.now();        System.out.println(localDateTime);        System.out.println(localDate);        System.out.println(localTime);        // 實(shí)例化方式二:of() 可以自定義時(shí)間,無 Date 中偏移量的問題        LocalDateTime localDateTime1 = LocalDateTime.of(2020, 10, 1, 4, 23, 43);        System.out.println(localDateTime1);        // getXxx() 獲取相關(guān)屬性        System.out.println(localDateTime.getDayOfMonth());        System.out.println(localDateTime.getDayOfWeek());        System.out.println(localDateTime.getMonth());        System.out.println(localDateTime.getMonthValue());        System.out.println(localDateTime.getMinute());        // withXxxx() 設(shè)置相關(guān)屬性, 具有不可變性        LocalDate localDate1 = localDate.withDayOfMonth(20);        System.out.println(localDate1);        LocalDateTime localDateTime2 = localDateTime.withHour(16);        System.out.println(localDateTime);        System.out.println(localDateTime2);        //plusXxx() 在現(xiàn)有基礎(chǔ)上加上指定數(shù)據(jù)        LocalDateTime localDateTime3 = localDateTime.plusMonths(3);        System.out.println(localDateTime);        System.out.println(localDateTime3);        // minusXxx() 在現(xiàn)有基礎(chǔ)上減去指定數(shù)據(jù)        LocalDateTime localDateTime4 = localDateTime.minusMonths(3);        System.out.println(localDateTime);        System.out.println(localDateTime4);    }}

          4.2 Instant 類的使用

          • Instant : 時(shí)間線上的瞬時(shí)點(diǎn). 這可能被用來記錄應(yīng)用程序中的事件時(shí)間戳.

          方法 :

          • now() 靜態(tài)方法, 返回 UTC 時(shí)區(qū)的 Instant 類對(duì)象

          • atOffset() 添加 默認(rèn)時(shí)區(qū) 與 當(dāng)前需要時(shí)區(qū) 的 時(shí)間 的 偏移量

          • toEpochMilli() 獲取 1970年1月1日0時(shí)0分0秒 (UTC) 開始的毫秒數(shù)

          • ofEpochMilli() 靜態(tài)方法, 通過給定的毫秒數(shù)獲取 Instant 的實(shí)例

          Demo :

          package com.broky.commonClass;import org.junit.jupiter.api.Test;import java.time.*;/** * jdk 8 中的時(shí)間日期 api * * @author 13roky * @date 2021-05-10 7:05 */public class JDK8DateTimeTest {    /*    Instant 的使用     */    @Test    public void test02() {        // now : 獲取本初子午線的時(shí)間        Instant instant = Instant.now(); //格林威治時(shí)間        System.out.println(instant);        // 添加 默認(rèn)時(shí)區(qū) 與 當(dāng)前需要時(shí)區(qū) 的 時(shí)間 的 偏移量        OffsetDateTime offsetDateTime = instant.atOffset(ZoneOffset.ofHours(8));        System.out.println(offsetDateTime);        // 獲取 1970年1月1日0時(shí)0分0秒 (UTC) 開始的毫秒數(shù)        long milli = instant.toEpochMilli();        System.out.println(milli);                // ofEpochMilli 通過給定的毫秒數(shù)獲取 Instant 的實(shí)例        Instant instant1 = Instant.ofEpochMilli(1620783200875L);        System.out.println(instant1);    }}

          4.3 DateTimeFormatter 類

          用于格式化和解析 LocalDate、LocalTime、LocalDateTime

          類似于 SimpleDateFormat

          格式化方式 :

          1. 預(yù)定義的標(biāo)準(zhǔn)格式。如:ISO_LOCAL_DATE_TIME;ISO_LOCAL_DATE;ISO_LOCAL_TIME;

          2. 本地化相關(guān)的格式。如:ofLocalizedDateTime(FormatStyle.LONG);

          3. 自定義的格式。如:ofPattern("yyyy-MM-dd hh:mm:ss E");

          解析方式 :

          1. parse() 方法

          Demo :

          package com.broky.commonClass;import org.junit.jupiter.api.Test;import java.time.*;import java.time.format.DateTimeFormatter;import java.time.format.FormatStyle;import java.time.temporal.TemporalAccessor;/** * jdk 8 中的時(shí)間日期 api * * @author 13roky * @date 2021-05-10 7:05 */public class JDK8DateTimeTest {    /*    DateTimeFormatter:格式化或解析日期、時(shí)間    類似于SimpleDateFormat     */    @Test    public void test03() {        // 方式一:預(yù)定義的標(biāo)準(zhǔn)格式。如:ISO_LOCAL_DATE_TIME;ISO_LOCAL_DATE;ISO_LOCAL_TIME;        DateTimeFormatter formatter = DateTimeFormatter.ISO_LOCAL_DATE_TIME;        LocalDateTime localDateTime = LocalDateTime.now();        System.out.println(localDateTime);        String s = formatter.format(localDateTime);        System.out.println(s);        // 因?yàn)槭褂脴?biāo)準(zhǔn)格式進(jìn)行格式化,所以 localDateTime 格式化前后的值基本沒有變化,但是類型變變?yōu)榱?nbsp;String        // 解析:字符串-->日期        TemporalAccessor parse = formatter.parse("2021-05-12T20:48:52.1539765");        System.out.println(parse);        // 方式二:        // 本地化相關(guān)的格式。如:ofLocalizedDateTime(FormatStyle.LONG);        // FormatStyle.LONG / FormatStyle.MEDIUM / FormatStyle.SHORT : 適用于LocalDateTime        DateTimeFormatter formatter1 = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM);        String s1 = formatter1.format(localDateTime);        System.out.println(s1);        // 本地化相關(guān)的格式。如:ofLocalizedDate()        // FormatStyle.FULL / FormatStyle.LONG / FormatStyle.MEDIUM / FormatStyle.SHORT : 適用于LocalDateTime        DateTimeFormatter formatter2 = DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL);        String s2 = formatter2.format(LocalDate.now());        System.out.println(s2);        /*        可能會(huì)報(bào)錯(cuò) : java.time.DateTimeException: Unable to extract ZoneId from temporal        參考:https://stackoverflow.com/questions/59531046/java-time-datetimeexception-unable-to-extract-zoneid-from-temporal         */        // 方式三:自定義的格式。如:ofPattern("yyyy-MM-dd hh:mm:ss E");        DateTimeFormatter formatter3 = DateTimeFormatter.ofPattern("yyyy-MM-dd hh:mm:ss");        String s3 = formatter3.format(localDateTime);        System.out.println(s3);        // 解析        TemporalAccessor parse1 = formatter3.parse("2021-05-12 09:24:47");        System.out.println(parse1);    }}

          4.4 其它API

          • ZoneId:該類中包含了所有的時(shí)區(qū)信息,一個(gè)時(shí)區(qū)的ID,如 Europe/Paris

          • ZonedDateTime:一個(gè)在ISO-8601日歷系統(tǒng)時(shí)區(qū)的日期時(shí)間,如 2007-12- 03T10:15:30+01:00 Europe/Paris。

            • 其中每個(gè)時(shí)區(qū)都對(duì)應(yīng)著ID,地區(qū)ID都為“{區(qū)域}/{城市}”的格式,例如:Asia/Shanghai等

          • Clock:使用時(shí)區(qū)提供對(duì)當(dāng)前即時(shí)、日期和時(shí)間的訪問的時(shí)鐘。

          • 持續(xù)時(shí)間:Duration,用于計(jì)算兩個(gè)“時(shí)間”間隔

          • 日期間隔:Period,用于計(jì)算兩個(gè)“日期”間隔

          • TemporalAdjuster : 時(shí)間校正器。有時(shí)我們可能需要獲取例如:將日期調(diào)整 到“下一個(gè)工作日”等操作。

          • TemporalAdjusters : 該類通過靜態(tài)方法 (firstDayOfXxx()/lastDayOfXxx()/nextXxx())提供了大量的常用 TemporalAdjuster 的實(shí)現(xiàn)。

          5. Comparable 和 Comparator 接口

          5.1 Comparable 接口 自然排序

          用于對(duì)象與對(duì)象的比較, Comparable屬于自然排序

          說明:

          Java中的對(duì)象, 正常情況下, 只能進(jìn)行比較:==或!= 不能使用>或<

          但是在開發(fā)場景中, 我們需要對(duì)多個(gè)對(duì)象進(jìn)行排序, 言外之意, 就需要比較對(duì)象的大小

          使用兩個(gè)接口中的任何一個(gè)來實(shí)現(xiàn): Comparable 或 Comparator

          Comparable 接口的使用舉例 :

          1. 像 String, 包裝類等實(shí)現(xiàn)了 Comparable 接口, 重寫了 `compareTo(obj)` 方法, 給出了比較兩個(gè)對(duì)象
          2. 像 String, 包裝類重寫了`compareTo()`方法以后, 進(jìn)行了從小到大的排列
          3. 重寫 `compareTo(obj)` 的規(guī)則:
             如果當(dāng)前對(duì)象 this 等于形參對(duì)象 obj, 則返回為零
             如果當(dāng)前對(duì)象 this 小于形參對(duì)象 obj, 則返回負(fù)整數(shù)
             如果當(dāng)前對(duì)象 this 大于形參對(duì)象 obj, 則返回正整數(shù)
          4. **對(duì)于自定義類來說**, 如果需要排序, 我們可以讓自定義類實(shí)現(xiàn) Comparable 接口, 重寫 `compareTo(obj)` 方法并在 `compareTO(obj)` 方法中指明如何排序

          Demo:

          package com.broky.commonClass;import org.junit.jupiter.api.Test;import java.util.Arrays;/** * 1) 說明: Java中的對(duì)象, 正常情況下, 只能進(jìn)行比較:==或!= 不能使用>或< *          但是在開發(fā)場景中, 我們需要對(duì)多個(gè)對(duì)象進(jìn)行排序, 言外之意, 就需要比較對(duì)象的大小 *          如何實(shí)現(xiàn)? 使用兩個(gè)接口中的任何一個(gè): Comparable 或 Comparator * 2) Comparable 接口的使用 * * @author 13roky * @date 2021-05-12 22:15 */public class CompareTest {    /*    Comparable 接口的使用舉例: 自然排序    1. 像 String, 包裝類等實(shí)現(xiàn)了 Comparable 接口, 重寫了 compareTo(obj) 方法, 給出了比較兩個(gè)對(duì)象    2. 像 String, 包裝類重寫了compareTo()方法以后,進(jìn)行了從小到大的排列    3. 重寫 compareTo(obj) 的規(guī)則:        如果當(dāng)前對(duì)象 this 等于形參對(duì)象 obj, 則返回為零        如果當(dāng)前對(duì)象 this 小于形參對(duì)象 obj, 則返回負(fù)整數(shù)        如果當(dāng)前對(duì)象 this 大于形參對(duì)象 obj, 則返回正整數(shù)    4. 對(duì)于自定義類來說, 如果需要排序, 我們可以讓自定義類實(shí)現(xiàn) Comparable 接口, 重寫compareTo(obj) 方法        在 compareTO(obj) 方法中知名如何排序     */    @Test    public void test01(){        String[] arr = new String[]{"aa","cc","kk","mm","gg","jj","dd"};        Arrays.sort(arr);        System.out.println(Arrays.toString(arr));    }    @Test    public void test02() {        Goods[] arr = new Goods[4];        arr[0] = new Goods("lenovoMouse",34);        arr[1] = new Goods("dellMouse",43);        arr[2] = new Goods("xiaomiMouse",12);        arr[3] = new Goods("huaweiMouse",65);        arr[3] = new Goods("MicroSoftiMouse",12);          // 根據(jù)arr所對(duì)應(yīng)類的CompareTo方法排序        Arrays.sort(arr);        System.out.println(Arrays.toString(arr));    }}
          package com.broky.commonClass;/** * 商品類 實(shí)現(xiàn)Comparable方法 * * @author 13roky * @date 2021-05-12 22:42 */public class Goods implements Comparable {    private String name;    private double price;    public Goods() {    }    public Goods(String name, double price) {        this.name = name;        this.price = price;    }    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public double getPrice() {        return price;    }    public void setPrice(double price) {        this.price = price;    }    @Override    public String toString() {        return "Goods{" + "name='" + name + '\'' + ", price=" + price + '}';    }    // 指明商品比較大小的方式:按照價(jià)格從低到高排序,再按照產(chǎn)品名稱從第到高排序    @Override    public int compareTo(Object o) {        if (o instanceof Goods) {            // 方式一            Goods goods = (Goods) o;            if (this.price > goods.price) {                return 1;            } else if (this.price < goods.price) {                return -1;            } else {                // 字符串類型的本身就有 compareTo 方法                return this.name.compareTo(goods.name);                // return -this.name.compareTo(goods.name); 加了負(fù)號(hào)變成了從高到低排            }            // 方式二            //return Double.compare(this.price,goods.price);        }        throw new RuntimeException("傳入的數(shù)據(jù)類型不一致");    }}

          5.2 Comparator 接口 定制排序

          根據(jù)定制的規(guī)則進(jìn)行比較, Comparator屬于定制排序

          當(dāng)元素的類型沒有實(shí)現(xiàn)java.lang.Comparable 接口而又不方便修改代碼,或者實(shí)現(xiàn)了java.lang.Comparable 接口的排序規(guī)則不適合當(dāng)前的操作, 那么可以使用 Compare(obj o1,obj o2)方法, 比較o1和o2的大小

          說明 :

          1. 當(dāng)元素的類型沒有實(shí)現(xiàn)java.lang.Comparable接口而又不方便修改代碼, 或者實(shí)現(xiàn)了java.lang.Comparable接口的排序規(guī)則不適合當(dāng)前的操作,那么可以考慮使用 Comparator 的對(duì)象來排序,強(qiáng)行對(duì)多個(gè)對(duì)象進(jìn)行整體排序的比較。

          使用 :

          1. 在 Arrays.sort() 方法中使用匿名內(nèi)部類的方法實(shí)現(xiàn)定制排序 (詳情見Demo)

          **Comparable 接口與 Comparator 的使用的對(duì)比 : **

          1. Comparable 接口的方式一旦實(shí)現(xiàn),保證 Comparable 接口實(shí)現(xiàn)類的對(duì)象在任何位置都可以比較大小

          2. Comparator 接口屬于臨時(shí)性的比較.

          Demo :

          package com.broky.commonClass;import org.junit.jupiter.api.Test;import java.util.Arrays;import java.util.Comparator;/** * 1) 說明: Java中的對(duì)象, 正常情況下, 只能進(jìn)行比較:==或!= 不能使用>或< *          但是在開發(fā)場景中, 我們需要對(duì)多個(gè)對(duì)象進(jìn)行排序, 言外之意, 就需要比較對(duì)象的大小 *          如何實(shí)現(xiàn)? 使用兩個(gè)接口中的任何一個(gè): Comparable 或 Comparator * 2) Comparable 接口與 Comparator 的使用的對(duì)比 *          Comparable 接口的方式一旦實(shí)現(xiàn),保證 Comparable 接口實(shí)現(xiàn)類的對(duì)象在任何位置都可以比較大小 *          Comparator 接口屬于臨時(shí)性的比較. * * @author 13roky * @date 2021-05-12 22:15 */public class CompareTest {        /*    Comparator 接口的使用: 定制排序    1. 背景    當(dāng)元素的類型沒有實(shí)現(xiàn)java.lang.Comparable 接口而又不方便修改代碼,    或者實(shí)現(xiàn)了java.lang.Comparable 接口的排序規(guī)則不適合當(dāng)前的操作    那么可以使用 Compare(obj o1,obj o2)方法, 比較o1和o2的大小    2. 重寫 Compare(obj o1,obj o2) 方法, 比較o1和o2的大小    如果方法返回正數(shù),則表示o1大于o2    如果方法返回負(fù)數(shù),則表示01小于02    如果方法返回0, 則表示相等     */    @Test    public void test03(){        // test1        String[] arr = new String[]{"aa","cc","kk","mm","gg","jj","dd"};        // 從大到小排序        Arrays.sort(arr, new Comparator() {            @Override            public int compare(Object o1, Object o2) {                if(o1 instanceof String && o2 instanceof String){                    String s1 = (String) o1;                    String s2 = (String) o2;                    return -s1.compareTo(s2);                }                throw new RuntimeException("輸入的類型不一致");            }        });        System.out.println(Arrays.toString(arr));    }    @Test    public void test04() {        Goods[] arr = new Goods[5];        arr[0] = new Goods("lenovoMouse",34);        arr[1] = new Goods("huaweiMouse",43);        arr[2] = new Goods("xiaomiMouse",12);        arr[3] = new Goods("huaweiMouse",65);        arr[4] = new Goods("microSoftiMouse",12);        Arrays.sort(arr,new Comparator(){            // 指明商品比較大小的方式:再按照產(chǎn)品名稱從第到高排序, 按照價(jià)格從高到低排序            @Override            public int compare(Object o1, Object o2) {                if (o1 instanceof Goods && o2 instanceof Goods){                    Goods g1 = (Goods) o1;                    Goods g2 = (Goods) o2;                    if (g1.getName().equals(g2.getName())){                        return -Double.compare(g1.getPrice(),g2.getPrice());                    }else {                        return g1.getName().compareTo(g2.getName());                    }                }                throw new RuntimeException("輸入的數(shù)據(jù)類型不一致");            }        });        System.out.println(Arrays.toString(arr));    }}

          6. System 類

          System類代表系統(tǒng),系統(tǒng)級(jí)的很多屬性和控制方法都放置在該類的內(nèi)部。該類位于java.lang包。

          由于該類的構(gòu)造器是private的,所以無法創(chuàng)建該類的對(duì)象,也就是無法實(shí) 例化該類。其內(nèi)部的成員變量和成員方法都是static的,所以也可以很方便 的進(jìn)行調(diào)用。

          ? 成員方法 ? native long currentTimeMillis():該方法的作用是返回當(dāng)前的計(jì)算機(jī)時(shí)間,時(shí)間的表達(dá)格式為當(dāng)前計(jì)算機(jī)時(shí) 間和GMT時(shí)間(格林威治時(shí)間)1970年1月1號(hào)0時(shí)0分0秒所差的毫秒數(shù)。? void exit(int status):該方法的作用是退出程序。其中status的值為0代表正常退出,非零代表 異常退出。使用該方法可以在圖形界面編程中實(shí)現(xiàn)程序的退出功能等。

          成員變量 :

          • System類內(nèi)部包含in、out和err三個(gè)成員變量,分別代表標(biāo)準(zhǔn)輸入流 (鍵盤輸入),標(biāo)準(zhǔn)輸出流(顯示器)和標(biāo)準(zhǔn)錯(cuò)誤輸出流(顯示器)。

          成員方法 :

          • native long currentTimeMillis():該方法的作用是返回當(dāng)前的計(jì)算機(jī)時(shí)間,時(shí)間的表達(dá)格式為當(dāng)前計(jì)算機(jī)時(shí) 間和GMT時(shí)間(格林威治時(shí)間)1970年1月1號(hào)0時(shí)0分0秒所差的毫秒數(shù)。

          • void exit(int status):該方法的作用是退出程序。其中status的值為0代表正常退出,非零代表 異常退出。使用該方法可以在圖形界面編程中實(shí)現(xiàn)程序的退出功能等。

          • void gc():該方法的作用是請求系統(tǒng)進(jìn)行垃圾回收。至于系統(tǒng)是否立刻回收,則 取決于系統(tǒng)中垃圾回收算法的實(shí)現(xiàn)以及系統(tǒng)執(zhí)行時(shí)的情況。

          • String getProperty(String key):該方法的作用是獲得系統(tǒng)中屬性名為key的屬性對(duì)應(yīng)的值。系統(tǒng)中常見 的屬性名以及屬性的作用如下表所示:

          7. Math類

          java.lang.Math提供了一系列靜態(tài)方法用于科學(xué)計(jì)算。

          其方法的參數(shù)和返回 值類型一般為double型。

          方法 :

          • abs 絕對(duì)值

          • acos,asin,atan,cos,sin,tan 三角函數(shù)

          • sqrt 平方根

          • pow(double a,doble b) a的b次冪

          • log 自然對(duì)數(shù)

          • exp e為底指數(shù)

          • max(double a,double b)

          • min(double a,double b)

          • random() 返回0.0到1.0的隨機(jī)數(shù)

          • long round(double a) double型數(shù)據(jù)a轉(zhuǎn)換為long型(四舍五入)

          • toDegrees(double angrad) 弧度—>角度

          • toRadians(double angdeg) 角度—>弧度

          8. BigInteger 與 BigDecimal 類

          用于操作較大的整數(shù)

          8.1 BigInteger 類

          類似于整形

          說明 :

          1. Integer類作為int的包裝類,能存儲(chǔ)的最大整型值為2 31-1,Long類也是有限的, 最大為2 63-1。如果要表示再大的整數(shù),不管是基本數(shù)據(jù)類型還是他們的包裝類 都無能為力,更不用說進(jìn)行運(yùn)算了。

          2. java.math包的BigInteger可以表示不可變的任意精度的整數(shù)。BigInteger 提供 所有 Java 的基本整數(shù)操作符的對(duì)應(yīng)物,并提供 java.lang.Math 的所有相關(guān)方法。另外,BigInteger 還提供以下運(yùn)算:模算術(shù)、GCD 計(jì)算、質(zhì)數(shù)測試、素?cái)?shù)生成、 位操作以及一些其他操作。

          構(gòu)造器 :

          • BigInteger(String val):根據(jù)字符串構(gòu)建 BigInteger 對(duì)象

          常用方法 :

          public BigInteger abs():返回此 BigInteger 的絕對(duì)值的 BigInteger。

          BigInteger add(BigInteger val) :返回其值為 (this + val) 的 BigInteger

          BigInteger subtract(BigInteger val) :返回其值為 (this - val) 的 BigInteger

          BigInteger multiply(BigInteger val) :返回其值為 (this * val) 的 BigInteger

          BigInteger divide(BigInteger val) :返回其值為 (this / val) 的 BigInteger。整數(shù) 相除只保留整數(shù)部分。

          BigInteger remainder(BigInteger val) :返回其值為 (this % val) 的 BigInteger。

          BigInteger[] divideAndRemainder(BigInteger val):返回包含 (this / val) 后跟 (this % val) 的兩個(gè) BigInteger 的數(shù)組。

          BigInteger pow(int exponent) :返回其值為 (thisexponent) 的 BigInteger。

          8.2 BigDecimal 類

          類似于浮點(diǎn)型

          說明 :

          1. 一般的Float類和Double類可以用來做科學(xué)計(jì)算或工程計(jì)算,但在商業(yè)計(jì)算中, 要求數(shù)字精度比較高,故用到j(luò)ava.math.BigDecimal類

          2. BigDecimal 類支持不可變的、任意精度的有符號(hào)十進(jìn)制定點(diǎn)數(shù)。

          構(gòu)造器 :

          • public BigDecimal(double val)

          • public BigDecimal(String val)

          常用方法 :

          public BigDecimal add(BigDecimal augend)

          public BigDecimal subtract(BigDecimal subtrahend)

          public BigDecimal multiply(BigDecimal multiplicand)

          public BigDecimal divide(BigDecimal divisor, int scale, int roundingMode)

          Demo :

          package com.broky.commonClass;

          import org.junit.jupiter.api.Test;

          import java.math.BigDecimal;
          import java.math.BigInteger;

          /**
           * @author 13roky
           * @date 2021-05-13 12:56
           */
          public class OtherClassTest {
              
              @Test
              public void testBigInteger() {
                  BigInteger bi = new BigInteger("12433241123");
                  BigDecimal bd = new BigDecimal("12435.351");
                  BigDecimal bd2 = new BigDecimal("11");
                  System.out.println(bi);
                  // BigDecimal.ROUND_HALF_UP 四舍五入
                  System.out.println(bd.divide(bd2, BigDecimal.ROUND_HALF_UP));
                  System.out.println(bd.divide(bd2, 15, BigDecimal.ROUND_HALF_UP));
              }

          }






          粉絲福利:Java從入門到入土學(xué)習(xí)路線圖

          ??????

          ??長按上方微信二維碼 2 秒


          感謝點(diǎn)贊支持下哈 

          瀏覽 57
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  大鸡巴导航| 天天日天天肏 | 日本午夜影院 | 黄色电影免费在线 | 白丝自慰喷水 |