【JavaSE五天速通|第三篇】常用API與日期類篇

適合有其他語言基礎想快速入門JavaSE的。用的資料是 Java入門基礎視頻教程 ,從中摘取了筆者認為與其他語言不同或需要重點學習的內容

常用API與日期類只需要有印象即可,用到了再來這查

day04 常用API

一、StringBuilder類

  • StringBuilder代表可變字符串對象,相當于是一個容器,它里面的字符串是可以改變的,就是用來操作字符串的。
  • 好處:StringBuilder比String合適做字符串的修改操作,效率更高,代碼也更加簡潔。
public class Test{public static void main(String[] args){StringBuilder sb = new StringBuilder("itehima");//1.拼接內容sb.append(12);sb.append("黑馬");sb.append(true);//2.append方法,支持臨時編程sb.append(666).append("黑馬2").append(666);System.out.println(sb); //打印:12黑馬666黑馬2666//3.反轉操作sb.reverse();System.out.println(sb); //打印:6662馬黑666馬黑21//4.返回字符串的長度System.out.println(sb.length());//5.StringBuilder還可以轉換為字符串String s = sb.toString();System.out.println(s); //打印:6662馬黑666馬黑21}
}

直接使用String拼接(s = s + "abc")100萬次,等了1分鐘,還沒結束,我等不下去了;但是使用StringBuilder(sb.append("abc"))做拼接,不到1秒鐘出結果了。

二、StringJoiner類

是因為我們前面使用StringBuilder拼接字符串的時,代碼寫起來還是有一點麻煩,而StringJoiner號稱是拼接神器,不僅效率高,而且代碼簡潔。

public class Test{public static void main(String[] args){StringJoiner s = new StringJoiner(",");s.add("java1");s.add("java2");s.add("java3");System.out.println(s); //結果為: java1,java2,java3//參數1:間隔符//參數2:開頭//參數3:結尾StringJoiner s1 = new StringJoiner(",","[","]");s1.add("java1");s1.add("java2");s1.add("java3");System.out.println(s1); //結果為: [java1,java2,java3]}
}

三、Math類

該類提供了很多個進行數學運算的方法,如求絕對值,求最大值,四舍五入等

public class MathTest {public static void main(String[] args) {// 目標:了解下Math類提供的常見方法。// 1、public static int abs(int a):取絕對值(拿到的結果一定是正數)//    public static double abs(double a)System.out.println(Math.abs(-12)); // 12System.out.println(Math.abs(123)); // 123System.out.println(Math.abs(-3.14)); // 3.14// 2、public static double ceil(double a): 向上取整System.out.println(Math.ceil(4.0000001)); // 5.0System.out.println(Math.ceil(4.0)); // 4.0// 3、public static double floor(double a): 向下取整System.out.println(Math.floor(4.999999)); // 4.0System.out.println(Math.floor(4.0)); // 4.0// 4、public static long round(double a):四舍五入System.out.println(Math.round(3.4999)); // 3System.out.println(Math.round(3.50001)); // 4// 5、public static int max(int a, int b):取較大值//   public static int min(int a, int b):取較小值System.out.println(Math.max(10, 20)); // 20System.out.println(Math.min(10, 20)); // 10// 6、 public static double pow(double a, double b):取次方System.out.println(Math.pow(2, 3)); // 2的3次方   8.0System.out.println(Math.pow(3, 2)); // 3的2次方   9.0// 7、public static double random(): 取隨機數 [0.0 , 1.0) (包前不包后)System.out.println(Math.random());}
}

四、System類

這是系統類,提供了一些獲取系統數據的方法。比如獲取系統時間

public class SystemTest {public static void main(String[] args) {// 1、public static void exit(int status)://   終止當前運行的Java虛擬機。//   該參數用作狀態代碼; 按照慣例,非零狀態代碼表示異常終止。System.exit(0); // 人為的終止虛擬機。(不要使用)// 2、public static long currentTimeMillis()://    獲取當前系統的時間//    返回的是long類型的時間毫秒值:指的是從1970-1-1 0:0:0開始走到此刻的總的毫秒值,1s = 1000mslong time = System.currentTimeMillis();System.out.println(time);for (int i = 0; i < 1000000; i++) {System.out.println("輸出了:" + i);}long time2 = System.currentTimeMillis();System.out.println((time2 - time) / 1000.0 + "s");}
}

五、Runtime類

再學習一個Java的運行時類,叫Runtime類。這個類可以用來獲取JVM的一些信息,也可以用這個類去執行其他的程序

public class RuntimeTest {public static void main(String[] args) throws IOException, InterruptedException {// 1、public static Runtime getRuntime() 返回與當前Java應用程序關聯的運行時對象。Runtime r = Runtime.getRuntime();// 2、public void exit(int status) 終止當前運行的虛擬機,該參數用作狀態代碼; 按照慣例,非零狀態代碼表示異常終止。// r.exit(0);// 3、public int availableProcessors(): 獲取虛擬機能夠使用的處理器數。System.out.println(r.availableProcessors());// 4、public long totalMemory() 返回Java虛擬機中的內存總量。System.out.println(r.totalMemory()/1024.0/1024.0 + "MB"); // 1024 = 1K     1024 * 1024 = 1M// 5、public long freeMemory() 返回Java虛擬機中的可用內存量System.out.println(r.freeMemory()/1024.0/1024.0 + "MB");// 6、public Process exec(String command) 啟動某個程序,并返回代表該程序的對象。// r.exec("D:\\soft\\XMind\\XMind.exe");Process p = r.exec("QQ");Thread.sleep(5000); // 讓程序在這里暫停5s后繼續往下走!!p.destroy(); // 銷毀!關閉程序!}
}

六、BigDecimal類

接下來我們學習的這個類叫BigDecimal,至于它是干什么用的,我們先不說。我們先看一段代碼,看這個代碼有什么問題?再說BigDeimal這個類是干什么用的,這樣會更好理解一些。

public class Test {public static void main(String[] args) {System.out.println(0.1 + 0.2);System.out.println(1.0 - 0.32);System.out.println(1.015 * 100);System.out.println(1.301 / 100);}
}

運行以上代碼,我們會發現,結果并和我們想看到的不太一樣。

0.30000000000000004
0.6799999999999999
101.49999999999999
0.013009999999999999

為了解決浮點型運算時的精度損失的問題,Java給我們提供了BigDecimal類,它提供了一些方法可以對數據進行四則運算,而且不丟失精度,同時還可以保留指定的小數位

public class Test2 {public static void main(String[] args) {// 目標:掌握BigDecimal進行精確運算的方案。double a = 0.1;double b = 0.2;// 1、把浮點型數據封裝成BigDecimal對象,再來參與運算。// a、public BigDecimal(double val) 得到的BigDecimal對象是無法精確計算浮點型數據的。 注意:不推薦使用這個,// b、public BigDecimal(String val)  得到的BigDecimal對象是可以精確計算浮點型數據的。 可以使用。// c、public static BigDecimal valueOf(double val): 通過這個靜態方法得到的BigDecimal對象是可以精確運算的。是最好的方案。BigDecimal a1 = BigDecimal.valueOf(a);BigDecimal b1 = BigDecimal.valueOf(b);// 2、public BigDecimal add(BigDecimal augend): 加法BigDecimal c1 = a1.add(b1);System.out.println(c1);// 3、public BigDecimal subtract(BigDecimal augend): 減法BigDecimal c2 = a1.subtract(b1);System.out.println(c2);// 4、public BigDecimal multiply(BigDecimal augend): 乘法BigDecimal c3 = a1.multiply(b1);System.out.println(c3);// 5、public BigDecimal divide(BigDecimal b): 除法BigDecimal c4 = a1.divide(b1);System.out.println(c4);//        BigDecimal d1 = BigDecimal.valueOf(0.1);
//        BigDecimal d2 = BigDecimal.valueOf(0.3);
//        BigDecimal d3 = d1.divide(d2);
//        System.out.println(d3);// 6、public BigDecimal divide(另一個BigDecimal對象,精確幾位,舍入模式) : 除法,可以設置精確幾位。BigDecimal d1 = BigDecimal.valueOf(0.1);BigDecimal d2 = BigDecimal.valueOf(0.3);BigDecimal d3 = d1.divide(d2,  2, RoundingMode.HALF_UP); // 0.33System.out.println(d3);// 7、public double doubleValue() : 把BigDecimal對象又轉換成double類型的數據。//print(d3);//print(c1);double db1 = d3.doubleValue();double db2 = c1.doubleValue();print(db1);print(db2);}public static void print(double a){System.out.println(a);}
}

五、Date類

Java中是由這個類的對象用來表示日期或者時間。

Date對象記錄的時間是用毫秒值來表示的。Java語言規定,1970年1月1日0時0分0秒認為是時間的起點,此時記作0,那么1000(1秒=1000毫秒)就表示1970年1月1日0時0分1秒,依次內推。

在這里插入圖片描述

public class Test1Date {public static void main(String[] args) {// 目標:掌握Date日期類的使用。// 1、創建一個Date的對象:代表系統當前時間信息的。Date d = new Date();System.out.println(d); // Fri Sep 12 09:24:27 CST 2025// 2、拿到時間毫秒值。long time = d.getTime();System.out.println(time); // 1757640267698// 3、把時間毫秒值轉換成日期對象: 2s之后的時間是多少。time += 2 * 1000;Date d2 = new Date(time);System.out.println(d2); // Fri Sep 12 09:24:29 CST 2025// 4、直接把日期對象的時間通過setTime方法進行修改Date d3 = new Date();d3.setTime(time);System.out.println(d3); // Fri Sep 12 09:24:29 CST 2025}
}

六、SimpleDateFormat類

接下來我們學習的SimpleDateFormat類就可以轉換Date對象表示日期時間的顯示格式。

  • 我們把Date對象轉換為指定格式的日期字符串這個操作,叫做日期格式化,
  • 反過來把指定格式的日期符串轉換為Date對象的操作,叫做日期解析。

在這里插入圖片描述

注意:創建SimpleDateFormat對象時,在構造方法的參數位置傳遞日期格式,而日期格式是由一些特定的字母拼接而來的。我們需要記住常用的幾種日期/時間格式

字母	   表示含義
yyyy	年
MM		月
dd		日
HH		時
mm		分
ss		秒
SSS		毫秒"2022年12月12日" 的格式是 "yyyy年MM月dd日"
"2022-12-12 12:12:12" 的格式是 "yyyy-MM-dd HH:mm:ss"
按照上面的格式可以任意拼接,但是字母不能寫錯
public class Test2SimpleDateFormat {public static void main(String[] args) throws ParseException {// 目標:掌握SimpleDateFormat的使用。// 1、準備一些時間Date d = new Date();System.out.println(d); // Fri Sep 12 09:37:15 CST 2025long time = d.getTime();System.out.println(time); // 1757641035548// 2、格式化日期對象,和時間 毫秒值。SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss EEE a");String rs = sdf.format(d);String rs2 = sdf.format(time);System.out.println(rs); // 2025年09月12日 09:37:15 周五 上午System.out.println(rs2); // 2025年09月12日 09:37:15 周五 上午System.out.println("----------------------------------------------");// 目標:掌握SimpleDateFormat解析字符串時間 成為日期對象。String dateStr = "2022-12-12 12:12:11";// 1、創建簡單日期格式化對象 , 指定的時間格式必須與被解析的時間格式一模一樣,否則程序會出bug.SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");Date d2 = sdf2.parse(dateStr);System.out.println(d2); // Mon Dec 12 12:12:11 CST 2022}
}

七、Calendar類

我們再學習一個和日期相關的類,它是Calendar類。Calendar類表示日歷,它提供了一些比Date類更好用的方法。

比如下面的案例(需求:將2023年09月10日增加一個月),用Date類就不太好做,而用Calendar就特別方便。因為Calendar類提供了方法可以直接對日歷中的年、月、日、時、分、秒等進行運算。

Calendar

  • 代表的是系統此刻時間對應的日歷。
  • 通過它可以單獨獲取、修改時間中的年、月、日、時、分、秒等。

注意:calendar是可變對象,一旦修改后其對象本身表示的時間將產生變化

在這里插入圖片描述

public class Test4Calendar {public static void main(String[] args) {// 目標:掌握Calendar的使用和特點。// 1、得到系統此刻時間對應的日歷對象。Calendar now = Calendar.getInstance();System.out.println(now); // java.util.GregorianCalendar[time=1757641127867,...,YEAR=2025,MONTH=8,WEEK_OF_YEAR=37,WEEK_OF_MONTH=2,DAY_OF_MONTH=12,DAY_OF_YEAR=255,...// 2、獲取日歷中的某個信息int year = now.get(Calendar.YEAR);System.out.println(year); // 2025int days = now.get(Calendar.DAY_OF_YEAR);System.out.println(days); // 255// 3、拿到日歷中記錄的日期對象。Date d = now.getTime();System.out.println(d); // Fri Sep 12 09:38:47 CST 2025// 4、拿到時間毫秒值long time = now.getTimeInMillis();System.out.println(time); // 1757641127867// 5、修改日歷中的某個信息now.set(Calendar.MONTH, 9); // 修改月份成為10月份。now.set(Calendar.DAY_OF_YEAR, 125); // 修改成一年中的第125天。System.out.println(now); // java.util.GregorianCalendar[time=?,...,YEAR=2025,MONTH=9,WEEK_OF_YEAR=37,WEEK_OF_MONTH=2,DAY_OF_MONTH=12,DAY_OF_YEAR=125,...// 6、為某個信息增加或者減少多少now.add(Calendar.DAY_OF_YEAR, 100);now.add(Calendar.DAY_OF_YEAR, -10);now.add(Calendar.DAY_OF_MONTH, 6);now.add(Calendar.HOUR, 12);now.set(2026, 11, 22);System.out.println(now); // java.util.GregorianCalendar[time=?,...,YEAR=2026,MONTH=11,WEEK_OF_YEAR=32,WEEK_OF_MONTH=2,DAY_OF_MONTH=22,DAY_OF_YEAR=221,...}
}

八、為什么JDK8要新增日期類

public class Test {public static void main(String[] args) {// 傳統的時間類(Date、SimpleDateFormat、Calendar)存在如下問題:// 1、設計不合理,使用不方便,很多都被淘汰了。Date d = new Date();//System.out.println(d.getYear()); // 125(+1900=2025)Calendar c = Calendar.getInstance();int year = c.get(Calendar.YEAR);System.out.println(year); // 2025// 2、都是可變對象,修改后會丟失最開始的時間信息。// 3、線程不安全。// 4、不能精確到納秒,只能精確到毫秒。// 1秒 = 1000毫秒// 1毫秒 = 1000微妙// 1微妙 = 1000納秒}
}

九、JDK8日期、時間、日期時間

在這里插入圖片描述
JDK8新增的日期類分得更細致一些,比如表示年月日用LocalDate類、表示時間秒用LocalTime類、而表示年月日時分秒用LocalDateTime類等;除了這些類還提供了對時區、時間間隔進行操作的類等。它們幾乎把對日期/時間的所有操作都通過了API方法,用起來特別方便。
在這里插入圖片描述
先學習表示日期、時間、日期時間的類;有LocalDate、LocalTime、以及LocalDateTime類。仔細閱讀代碼,你會發現這三個類的用法套路都是一樣的。

public class Test1_LocalDate {public static void main(String[] args) {// 0、獲取本地日期對象(不可變對象)LocalDate ld = LocalDate.now(); // 年 月 日System.out.println(ld);// 1、獲取日期對象中的信息int year = ld.getYear(); // 年int month = ld.getMonthValue(); // 月(1-12)int day = ld.getDayOfMonth(); // 日int dayOfYear = ld.getDayOfYear();  // 一年中的第幾天int dayOfWeek = ld.getDayOfWeek().getValue(); // 星期幾System.out.println(year);System.out.println(day);System.out.println(dayOfWeek);// 2、直接修改某個信息: withYear、withMonth、withDayOfMonth、withDayOfYearLocalDate ld2 = ld.withYear(2099);LocalDate ld3 = ld.withMonth(12);System.out.println(ld2);System.out.println(ld3);System.out.println(ld);// 3、把某個信息加多少: plusYears、plusMonths、plusDays、plusWeeksLocalDate ld4 = ld.plusYears(2);LocalDate ld5 = ld.plusMonths(2);// 4、把某個信息減多少:minusYears、minusMonths、minusDays、minusWeeksLocalDate ld6 = ld.minusYears(2);LocalDate ld7 = ld.minusMonths(2);// 5、獲取指定日期的LocalDate對象: public static LocalDate of(int year, int month, int dayOfMonth)LocalDate ld8 = LocalDate.of(2099, 12, 12);LocalDate ld9 = LocalDate.of(2099, 12, 12);// 6、判斷2個日期對象,是否相等,在前還是在后: equals isBefore isAfterSystem.out.println(ld8.equals(ld9));// trueSystem.out.println(ld8.isAfter(ld)); // trueSystem.out.println(ld8.isBefore(ld)); // false}
}
public class Test2_LocalTime {public static void main(String[] args) {// 0、獲取本地時間對象LocalTime lt = LocalTime.now(); // 時 分 秒 納秒 不可變的System.out.println(lt);// 1、獲取時間中的信息int hour = lt.getHour(); //時int minute = lt.getMinute(); //分int second = lt.getSecond(); //秒int nano = lt.getNano(); //納秒// 2、修改時間:withHour、withMinute、withSecond、withNanoLocalTime lt3 = lt.withHour(10);LocalTime lt4 = lt.withMinute(10);LocalTime lt5 = lt.withSecond(10);LocalTime lt6 = lt.withNano(10);// 3、加多少:plusHours、plusMinutes、plusSeconds、plusNanosLocalTime lt7 = lt.plusHours(10);LocalTime lt8 = lt.plusMinutes(10);LocalTime lt9 = lt.plusSeconds(10);LocalTime lt10 = lt.plusNanos(10);// 4、減多少:minusHours、minusMinutes、minusSeconds、minusNanosLocalTime lt11 = lt.minusHours(10);LocalTime lt12 = lt.minusMinutes(10);LocalTime lt13 = lt.minusSeconds(10);LocalTime lt14 = lt.minusNanos(10);// 5、獲取指定時間的LocalTime對象:// public static LocalTime of(int hour, int minute, int second)LocalTime lt15 = LocalTime.of(12, 12, 12);LocalTime lt16 = LocalTime.of(12, 12, 12);// 6、判斷2個時間對象,是否相等,在前還是在后: equals isBefore isAfterSystem.out.println(lt15.equals(lt16)); // trueSystem.out.println(lt15.isAfter(lt)); // falseSystem.out.println(lt15.isBefore(lt)); // true}
}
public class Test3_LocalDateTime {public static void main(String[] args) {// 0、獲取本地日期和時間對象。LocalDateTime ldt = LocalDateTime.now(); // 年 月 日 時 分 秒 納秒System.out.println(ldt);// 1、可以獲取日期和時間的全部信息int year = ldt.getYear(); // 年int month = ldt.getMonthValue(); // 月int day = ldt.getDayOfMonth(); // 日int dayOfYear = ldt.getDayOfYear();  // 一年中的第幾天int dayOfWeek = ldt.getDayOfWeek().getValue();  // 獲取是周幾int hour = ldt.getHour(); //時int minute = ldt.getMinute(); //分int second = ldt.getSecond(); //秒int nano = ldt.getNano(); //納秒// 2、修改時間信息:// withYear withMonth withDayOfMonth withDayOfYear withHour// withMinute withSecond withNanoLocalDateTime ldt2 = ldt.withYear(2029);LocalDateTime ldt3 = ldt.withMinute(59);// 3、加多少:// plusYears  plusMonths plusDays plusWeeks plusHours plusMinutes plusSeconds plusNanosLocalDateTime ldt4 = ldt.plusYears(2);LocalDateTime ldt5 = ldt.plusMinutes(3);// 4、減多少:// minusDays minusYears minusMonths minusWeeks minusHours minusMinutes minusSeconds minusNanosLocalDateTime ldt6 = ldt.minusYears(2);LocalDateTime ldt7 = ldt.minusMinutes(3);// 5、獲取指定日期和時間的LocalDateTime對象:// public static LocalDateTime of(int year, Month month, int dayOfMonth, int hour,//                                  int minute, int second, int nanoOfSecond)LocalDateTime ldt8 = LocalDateTime.of(2029, 12, 12, 12, 12, 12, 1222);LocalDateTime ldt9 = LocalDateTime.of(2029, 12, 12, 12, 12, 12, 1222);// 6、 判斷2個日期、時間對象,是否相等,在前還是在后: equals、isBefore、isAfterSystem.out.println(ldt9.equals(ldt8));System.out.println(ldt9.isAfter(ldt));System.out.println(ldt9.isBefore(ldt));// 7、可以把LocalDateTime轉換成LocalDate和LocalTime// public LocalDate toLocalDate()// public LocalTime toLocalTime()// public static LocalDateTime of(LocalDate date, LocalTime time)LocalDate ld = ldt.toLocalDate();LocalTime lt = ldt.toLocalTime();LocalDateTime ldt10 = LocalDateTime.of(ld, lt);}
}

十、JDK8日期(時區)

接著,我們學習代表時區的兩個類。由于世界各個國家與地區的經度不同,各地區的時間也有所不同,因此會劃分為不同的時區。每一個時區的時間也不太一樣。

public class Test4_ZoneId_ZonedDateTime {public static void main(String[] args) {// 目標:了解時區和帶時區的時間。// 1、ZoneId的常見方法:// public static ZoneId systemDefault(): 獲取系統默認的時區ZoneId zoneId = ZoneId.systemDefault();System.out.println(zoneId.getId());System.out.println(zoneId);// public static Set<String> getAvailableZoneIds(): 獲取Java支持的全部時區IdSystem.out.println(ZoneId.getAvailableZoneIds());// public static ZoneId of(String zoneId) : 把某個時區id封裝成ZoneId對象。ZoneId zoneId1 = ZoneId.of("America/New_York");// 2、ZonedDateTime:帶時區的時間。// public static ZonedDateTime now(ZoneId zone): 獲取某個時區的ZonedDateTime對象。ZonedDateTime now = ZonedDateTime.now(zoneId1);System.out.println(now);// 世界標準時間了ZonedDateTime now1 = ZonedDateTime.now(Clock.systemUTC());System.out.println(now1);// public static ZonedDateTime now():獲取系統默認時區的ZonedDateTime對象ZonedDateTime now2 = ZonedDateTime.now();System.out.println(now2);// Calendar instance = Calendar.getInstance(TimeZone.getTimeZone(zoneId1));}
}

十一、JDK8日期(Instant類)

接下來,我們來學習Instant這個類。通過獲取Instant的對象可以拿到此刻的時間,該時間由兩部分組成:從1970-01-01 00:00:00 開始走到此刻的總秒數+不夠1秒的納秒數。

可以用來獲取當前時間,也可以對時間進行加、減、獲取等操作。

作用:可以用來記錄代碼的執行時間,或用于記錄用戶操作某個事件的時間點。

在這里插入圖片描述

public class Test5_Instant {public static void main(String[] args) {// 1、創建Instant的對象,獲取此刻時間信息Instant now = Instant.now(); // 不可變對象// 2、獲取總秒數long second = now.getEpochSecond();System.out.println(second);// 3、不夠1秒的納秒數int nano = now.getNano();System.out.println(nano);System.out.println(now);Instant instant = now.plusNanos(111);// Instant對象的作用:做代碼的性能分析,或者記錄用戶的操作時間點Instant now1 = Instant.now();// 代碼執行。。。。Instant now2 = Instant.now();LocalDateTime l = LocalDateTime.now();}
}

十二、JDK8日期(格式化器)

它可以從來對日期進行格式化和解析。它代替了原來的SimpleDateFormat類(線程不安全)。

DateTimeFormatter:格式化器,用于時間的格式化、解析(線程安全)。

在這里插入圖片描述

public class Test6_DateTimeFormatter {public static void main(String[] args) {// 1、創建一個日期時間格式化器對象出來。DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm:ss");// 2、對時間進行格式化LocalDateTime now = LocalDateTime.now();System.out.println(now); // 2025-09-12T22:09:18.875713String rs = formatter.format(now); // 正向格式化System.out.println(rs); // 2025年09月12日 22:09:18// 3、格式化時間,其實還有一種方案。String rs2 = now.format(formatter); // 反向格式化System.out.println(rs2); // 2025年09月12日 22:09:18// 4、解析時間:解析時間一般使用LocalDateTime提供的解析方法來解析。String dateStr = "2029年12月12日 12:12:11";LocalDateTime ldt = LocalDateTime.parse(dateStr, formatter);System.out.println(ldt); // 2029-12-12T12:12:11}
}

十三、JDK8日期(Period類)

除以了上新增的類,JDK8還補充了兩個類,一個叫Period類、一個叫Duration類;這兩個類可以用來對計算兩個時間點的時間間隔

其中Period用來計算日期間隔(年、月、日),Duration用來計算時間間隔(時、分、秒、納秒)

先來演示Period類的用法,它的方法如下圖所示。可以用來計算兩個日期之間相隔的年、相隔的月、相隔的日。只能兩個計算LocalDate對象之間的間隔

在這里插入圖片描述

/*** 目標:掌握Period的作用:計算機兩個日期相差的年數,月數、天數。*/
public class Test7_Period {public static void main(String[] args) {LocalDate start = LocalDate.of(2029, 8, 10);LocalDate end = LocalDate.of(2029, 12, 15);// 1、創建Period對象,封裝兩個日期對象。Period period = Period.between(start, end);// 2、通過period對象獲取兩個日期對象相差的信息。System.out.println(period.getYears());System.out.println(period.getMonths());System.out.println(period.getDays());}
}

十四、JDK8日期(Duration類)

接下來,我們學習Duration類。它是用來表示兩個時間對象的時間間隔。可以用于計算兩個時間對象相差的天數、小時數、分數、秒數、納秒數;支持LocalTime、LocalDateTime、Instant等時間

在這里插入圖片描述

public class Test8_Duration {public static void main(String[] args) {LocalDateTime start = LocalDateTime.of(2025, 11, 11, 11, 10, 10);LocalDateTime end = LocalDateTime.of(2025, 11, 11, 11, 11, 11);// 1、得到Duration對象Duration duration = Duration.between(start, end);// 2、獲取兩個時間對象間隔的信息System.out.println(duration.toDays());// 間隔多少天System.out.println(duration.toHours());// 間隔多少小時System.out.println(duration.toMinutes());// 間隔多少分System.out.println(duration.toSeconds());// 間隔多少秒System.out.println(duration.toMillis());// 間隔多少毫秒System.out.println(duration.toNanos());// 間隔多少納秒}
}

day05 算法和數據結構

一、Arrays類

1.1 Arrays基本使用

Arrays是操作數組的工具類,它可以很方便的對數組中的元素進行遍歷、拷貝、排序等操作。

在這里插入圖片描述

public class ArraysTest1 {public static void main(String[] args) {// 1、public static String toString(類型[] arr): 返回數組的內容int[] arr = {10, 20, 30, 40, 50, 60};System.out.println(Arrays.toString(arr));// 2、public static 類型[] copyOfRange(類型[] arr, 起始索引, 結束索引) :拷貝數組(指定范圍,包前不包后)int[] arr2 = Arrays.copyOfRange(arr, 1, 4);System.out.println(Arrays.toString(arr2));// 3、public static copyOf(類型[] arr, int newLength):拷貝數組,可以指定新數組的長度。int[] arr3 = Arrays.copyOf(arr, 10);System.out.println(Arrays.toString(arr3));// 4、public static setAll(double[] array, IntToDoubleFunction generator):把數組中的原數據改為新數據又存進去。double[] prices = {99.8, 128, 100};//                  0     1    2// 把所有的價格都打八折,然后又存進去。// 匿名內部類Arrays.setAll(prices, new IntToDoubleFunction() {@Overridepublic double applyAsDouble(int value) {// value = 0  1  2return prices[value] * 0.8;}});System.out.println(Arrays.toString(prices));// 5、public static void sort(類型[] arr):對數組進行排序(默認是升序排序)Arrays.sort(prices);System.out.println(Arrays.toString(prices));}
}

IntToDoubleFunctionJava8新引入的函數式接口,它的作用是:

  • 接受一個 int 參數(在這里是數組索引)(在這個例子中,value 參數實際上是數組索引(0, 1, 2…),不是數組的原始值。)
  • 返回一個 double 值(新的數組元素值)

1.2 Arrays操作對象數組

剛才我們使用Arrays操作數組時,數組中存儲存儲的元素是int類型、double類型,是可以直接排序的,而且默認是升序排列。

如果數組中存儲的元素類型是自定義的對象,如何排序呢?接下來,我們就學習一下Arrays如何對對象數組進行排序

public class Student implements Comparable<Student>{private String name;private double height;private int age;public Student(String name, double height, int age) {this.name = name;this.height = height;this.age = age;}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", height=" + height +", age=" + age +'}';}
}

然后再寫一個測試類,往數組中存儲4個學生對象,代碼如下Arrays.sort(students);。此時,運行代碼你會發現是會報錯ClassCastException的。

public class ArraysTest2 {public static void main(String[] args) {// 目標:掌握如何對數組中的對象進行排序。Student[] students = new Student[4];students[0] = new Student("蜘蛛精", 169.5, 23);students[1] = new Student("紫霞", 163.8, 26);students[2] = new Student("紫霞", 163.8, 26);students[3] = new Student("至尊寶", 167.5, 24);// 1、public static void sort(類型[] arr):對數組進行排序。Arrays.sort(students);System.out.println(Arrays.toString(students));}
}

為了讓Arrays知道按照什么規則排序,我們有如下的兩種辦法。

排序方式1:Student類實現Comparable接口,同時重寫compareTo方法。Arrays的sort方法底層會根據compareTo方法的返回值是正數、負數、還是0來確定誰大、誰小、誰相等。代碼如下:

public class Student implements Comparable<Student>{private String name;private double height;private int age;//...get、set、空參數構造方法、有參數構造方法...自己補全// 指定比較規則// this  o@Overridepublic int compareTo(Student o) {// 約定1:認為左邊對象 大于 右邊對象 請您返回正整數// 約定2:認為左邊對象 小于 右邊對象 請您返回負整數// 約定3:認為左邊對象 等于 右邊對象 請您一定返回0/* if(this.age > o.age){return 1;}else if(this.age < o.age){return -1;}return 0;*///上面的if語句,也可以簡化為下面的一行代碼return this.age - o.age; // 按照年齡升序排列// return o.age - this.age; // 按照年齡降序排列}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", height=" + height +", age=" + age +'}';}
}

此時 Arrays.sort(students); 就不會報錯了

**排序方式2:**在調用Arrays.sort(數組,Comparator比較器);時,除了傳遞數組之外,傳遞一個Comparator比較器對象。Arrays的sort方法底層會根據Comparator比較器對象的compare方法方法的返回值是正數、負數、還是0來確定誰大、誰小、誰相等。代碼如下

public class ArraysTest2 {public static void main(String[] args) {// 目標:掌握如何對數組中的對象進行排序。Student[] students = new Student[4];students[0] = new Student("蜘蛛精", 169.5, 23);students[1] = new Student("紫霞", 163.8, 26);students[2] = new Student("紫霞", 163.8, 26);students[3] = new Student("至尊寶", 167.5, 24);// 2、public static <T> void sort(T[] arr, Comparator<? super T> c)// 參數一:需要排序的數組// 參數二:Comparator比較器對象(用來制定對象的比較規則)Arrays.sort(students, new Comparator<Student>() {@Overridepublic int compare(Student o1, Student o2) {// 制定比較規則了:左邊對象 o1   右邊對象 o2// 約定1:認為左邊對象 大于 右邊對象 請您返回正整數// 約定2:認為左邊對象 小于 右邊對象 請您返回負整數// 約定3:認為左邊對象 等于 右邊對象 請您一定返回0
//                if(o1.getHeight() > o2.getHeight()){
//                    return 1;
//                }else if(o1.getHeight() < o2.getHeight()){
//                    return -1;
//                }
//                return 0; // 升序return Double.compare(o1.getHeight(), o2.getHeight()); // 升序// return Double.compare(o2.getHeight(), o1.getHeight()); // 降序}});System.out.println(Arrays.toString(students));}
}

注意這里使用Double.compare(double d1, double d2) ,因為這個是兩個double做減法,前面說過會有精度損失的問題,所以不能直接相減。而如果是兩個int,直接做減法就好了。

當d1>d2時,Double.compare(double d1, double d2)返回正數(因為內部是return d1 - d2),此時Comparator.compare()會返回正數,則o1會排在o2后面(因為默認是升序

二、Lambda表達式

接下來,我們學習一個JDK8新增的一種語法形式,叫做Lambda表達式。作用:用于簡化匿名內部類代碼的書寫。

2.1 Lambda表達式基本使用

按照下面的格式來編寫Lamdba。

(被重寫方法的形參列表) -> {被重寫方法的方法體代碼;
}

需要給說明一下的是,在使用Lambda表達式之前,必須先有一個接口,而且接口中只能有一個抽象方法(注意:不能是抽象類,只能是接口)

像這樣的接口,我們稱之為函數式接口(接口中只有一個抽象方法),只有基于函數式接口的匿名內部類才能被Lambda表達式簡化。

public interface Swimming{void swim();
}
public class LambdaTest1 {public static void main(String[] args) {// 目標:認識Lambda表達式.//1.創建一個Swimming接口的匿名內部類對象Swimming s = new Swimming(){@Overridepublic void swim() {System.out.println("學生快樂的游泳~~~~");}};s.swim();//2.使用Lambda表達式對Swimming接口的匿名內部類進行簡化Swimming s1 = () -> {System.out.println("學生快樂的游泳~~~~");};s1.swim();}
}

好的,我們現在已經知道Lamdba表達式可以簡化基于函數式接口的匿名內部類的書寫。接下來,我們可以把剛才使用Arrays方法時的代碼,使用Lambda表達式簡化一下了。

public class LambdaTest2 {public static void main(String[] args) {// 目標:使用Lambda簡化函數式接口。double[] prices = {99.8, 128, 100};//1.把所有元素*0.8: 先用匿名內部類寫法Arrays.setAll(prices, new IntToDoubleFunction() {@Overridepublic double applyAsDouble(int value) {// value = 0  1  2return prices[value] * 0.8;}});//2.把所有元素*0.8: 改用Lamdba表達式寫法Arrays.setAll(prices, (int value) -> {return prices[value] * 0.8;});System.out.println(Arrays.toString(prices));System.out.println("-----------------------------------------------");Student[] students = new Student[4];students[0] = new Student("蜘蛛精", 169.5, 23);students[1] = new Student("紫霞", 163.8, 26);students[2] = new Student("紫霞", 163.8, 26);students[3] = new Student("至尊寶", 167.5, 24);//3.對數組中的元素按照年齡升序排列: 先用匿名內部類寫法Arrays.sort(students, new Comparator<Student>() {@Overridepublic int compare(Student o1, Student o2) {return Double.compare(o1.getHeight(), o2.getHeight()); // 升序}});//4.對數組中的元素按照年齡升序排列: 改用Lambda寫法Arrays.sort(students, (Student o1, Student o2) -> {return Double.compare(o1.getHeight(), o2.getHeight()); // 升序});System.out.println(Arrays.toString(students));}
}

Java編譯器通過目標類型推導(Target Type Inference)確定lambda表達式對應的函數式接口。(1)編譯器看到Arrays.sort(students, lambda表達式)。(2)查看Arrays.sort方法簽名,發現第二個參數期望Comparator<Student>類型

2.2 Lambda表達式省略規則

Java覺得代碼還不夠簡單,于是還提供了Lamdba表達式的幾種簡化寫法。具體的簡化規則如下

1.Lambda的標準格式(參數類型1 參數名1, 參數類型2 參數名2)->{...方法體的代碼...return 返回值;}2.在標準格式的基礎上()中的參數類型可以直接省略(參數名1, 參數名2)->{...方法體的代碼...return 返回值;}3.如果{}總的語句只有一條語句,則{}可以省略、return關鍵字、以及最后的“;”都可以省略(參數名1, 參數名2)-> 結果4.如果()里面只有一個參數,則()可以省略(參數名)->結果

接下來從匿名內部類開始、到Lambda標準格式、再到Lambda簡化格式,一步一步來簡化一下。

public class LambdaTest2 {public static void main(String[] args) {// 目標:使用Lambda簡化函數式接口。double[] prices = {99.8, 128, 100};//1.對數組中的每一個元素*0.8: 匿名內部類寫法Arrays.setAll(prices, new IntToDoubleFunction() {@Overridepublic double applyAsDouble(int value) {// value = 0  1  2return prices[value] * 0.8;}});//2.需求:對數組中的每一個元素*0.8,使用Lambda表達式標準寫法Arrays.setAll(prices, (int value) -> {return prices[value] * 0.8;});//3.使用Lambda表達式簡化格式1——省略參數類型Arrays.setAll(prices, (value) -> {return prices[value] * 0.8;});//4.使用Lambda表達式簡化格式2——省略()Arrays.setAll(prices, value -> {return prices[value] * 0.8;});//5.使用Lambda表達式簡化格式3——省略{}Arrays.setAll(prices, value -> prices[value] * 0.8 );System.out.println(Arrays.toString(prices));System.out.println("------------------------------------Student[] students = new Student[4];students[0] = new Student("蜘蛛精", 169.5, 23);students[1] = new Student("紫霞", 163.8, 26);students[2] = new Student("紫霞", 163.8, 26);students[3] = new Student("至尊寶", 167.5, 24);//1.使用匿名內部類Arrays.sort(students, new Comparator<Student>() {@Overridepublic int compare(Student o1, Student o2) {return Double.compare(o1.getHeight(), o2.getHeight()); // 升序}});//2.使用Lambda表達式表達式——標準格式Arrays.sort(students, (Student o1, Student o2) -> {return Double.compare(o1.getHeight(), o2.getHeight()); // 升序});//3.使用Lambda表達式表達式——省略參數類型Arrays.sort(students, ( o1,  o2) -> {return Double.compare(o1.getHeight(), o2.getHeight()); // 升序});//4.使用Lambda表達式表達式——省略{}Arrays.sort(students, ( o1,  o2) -> Double.compare(o1.getHeight(), o2.getHeight()));System.out.println(Arrays.toString(students));}
}

三、JDK8新特性(方法引用)

接下來我們學習JDK8的另一個新特性,叫做方法引用。我們知道Lambda是用來簡化匿名代碼的書寫格式的,而方法引用是用來進一步簡化Lambda表達式的,它簡化的更加過分。

3.1 靜態方法引用

類名::靜態方法

使用場景:如果某個Lambda表達式里只是調用一個靜態方法,并且前后參數的形式一致,就可以使用靜態方法引用。

public class Test1 {public static void main(String[] args) {Student[] students = new Student[4];students[0] = new Student("蜘蛛精", 169.5, 23);students[1] = new Student("紫霞", 163.8, 26);students[2] = new Student("紫霞", 163.8, 26);students[3] = new Student("至尊寶", 167.5, 24);// 原始寫法:對數組中的學生對象,按照年齡升序排序Arrays.sort(students, new Comparator<Student>() {@Overridepublic int compare(Student o1, Student o2) {return o1.getAge() - o2.getAge(); // 按照年齡升序排序}});// 使用Lambda簡化后的形式Arrays.sort(students, (o1, o2) -> o1.getAge() - o2.getAge());}
}

現在,我想要把這個Lambda表達式的方法體,用一個靜態方法代替

準備另外一個類CompareByData類,用于封裝Lambda表達式的方法體代碼

public class CompareByData {public static int compareByAge(Student o1, Student o2){return o1.getAge() - o2.getAge(); // 升序排序的規則}
}

現在我們就可以把Lambda表達式的方法體代碼,改為下面的樣子

Arrays.sort(students, (o1, o2) -> CompareByData.compareByAge(o1, o2));

Java為了簡化上面Lambda表達式的寫法,利用方法引用可以改進為下面的樣子。**實際上就是用類名調用方法,但是把參數給省略了。**這就是靜態方法引用

//靜態方法引用:類名::方法名
Arrays.sort(students, CompareByData::compareByAge);

3.2 實例方法引用

對象名::實例方法

使用場景:如果某個Lambda表達式里只是調用一個實例方法,并且前后參數的形式一致,就可以使用實例方法引用

現在,我想要把剛才的Lambda表達式Arrays.sort(students, (o1, o2) -> o1.getAge() - o2.getAge());的方法體,用一個實例方法代替。

在CompareByData類中,再添加一個實例方法,用于封裝Lambda表達式的方法體
在這里插入圖片描述
接下來,我們把Lambda表達式的方法體,改用對象調用方法

CompareByData compare = new CompareByData();
Arrays.sort(students, (o1, o2) -> compare.compareByAgeDesc(o1, o2)); // 降序

最后,再將Lambda表達式的方法體,直接改成方法引用寫法。實際上就是用對象名調用方法,但是省略的參數。這就是實例方法引用

CompareByData compare = new CompareByData();
Arrays.sort(students, compare::compareByAgeDesc); // 降序

3.2 特定類型的方法引用

類型::方法

使用場景:如果某個Lambda表達式里只是調用一個實例方法,并且前面參數列表中的第一個參數是作為方法的主調
后面的所有參數都是作為該實例方法的入參的,則此時就可以使用特定類型的方法引用。

這種特定類型的方法引用是沒有什么道理的,只是語法的一種約定,遇到這種場景,就可以這樣用。

public class Test2 {public static void main(String[] args) {String[] names = {"boby", "angela", "Andy" ,"dlei", "caocao", "Babo", "jack", "Cici"};// 要求忽略首字符大小寫進行排序。Arrays.sort(names, new Comparator<String>() {@Overridepublic int compare(String o1, String o2) {// 制定比較規則。o1 = "Andy"  o2 = "angela"return o1.compareToIgnoreCase(o2);}});//lambda表達式寫法Arrays.sort(names, ( o1,  o2) -> o1.compareToIgnoreCase(o2) );//特定類型的方法引用!Arrays.sort(names, String::compareToIgnoreCase);System.out.println(Arrays.toString(names));}
}

3.3 構造器引用

類名::new

使用場景:如果某個Lambda表達式里只是在創建對象,并且前后參數情況一致,就可以使用構造器引用。

學習最后一種方法引用的形式,叫做構造器引用。還是先說明一下,構造器引用在實際開發中應用的并不多,目前還沒有找到構造器的應用場景。所以大家在學習的時候,也只是關注語法就可以了。

現在,我們準備一個JavaBean類,Car類

因為方法引用是基于Lamdba表達式簡化的,所以也要按照Lamdba表達式的使用前提來用,需要一個函數式接口,接口中代碼的返回值類型是Car類型

interface CreateCar{Car create(String name, double price);
}

最后,再準備一個測試類,在測試類中創建CreateCar接口的實現類對象,先用匿名內部類創建、再用Lambda表達式創建,最后改用方法引用創建。同學們只關注格式就可以,不要去想為什么(語法就是這么設計的)。

public class Test3 {public static void main(String[] args) {// 1、創建這個接口的匿名內部類對象。CreateCar cc1 = new CreateCar(){@Overridepublic Car create(String name, double price) {return new Car(name, price);}};//2、使用匿名內部類改進CreateCar cc2 = (name,  price) -> new Car(name, price);//3、使用方法引用改進:構造器引用CreateCar cc3 = Car::new;//注意:以上是創建CreateCar接口實現類對象的幾種形式而已,語法一步一步簡化。//4、對象調用方法Car car = cc3.create("奔馳", 49.9);System.out.println(car);}
}

四、常見算法(跳過)

五、正則表達式

正則表達式其實是由一些特殊的符號組成的,它代表的是某種規則。

  • 正則表達式的作用1:用來校驗字符串數據是否合法
  • 正則表達式的作用2:可以從一段文本中查找滿足要求的內容

5.2 正則表達式書寫規則

這里需要用到一個方法叫matches(String regex)(判斷字符串是否匹配正則表達式,匹配返回true,不匹配返回false。)。這個方法時屬于String類的方法。

這個方法是用來匹配一個字符串是否匹配正則表達式的規則,參數需要調用者傳遞一個正則表達式。但是正則表達式不能亂寫,是有特定的規則的。
在這里插入圖片描述

public class RegexTest2 {public static void main(String[] args) {// 1、字符類(只能匹配單個字符)System.out.println("a".matches("[abc]"));    // [abc]只能匹配a、b、cSystem.out.println("e".matches("[abcd]")); // falseSystem.out.println("d".matches("[^abc]"));   // [^abc] 不能是abcSystem.out.println("a".matches("[^abc]"));  // falseSystem.out.println("b".matches("[a-zA-Z]")); // [a-zA-Z] 只能是a-z A-Z的字符System.out.println("2".matches("[a-zA-Z]")); // falseSystem.out.println("k".matches("[a-z&&[^bc]]")); // : a到z,除了b和cSystem.out.println("b".matches("[a-z&&[^bc]]")); // falseSystem.out.println("ab".matches("[a-zA-Z0-9]")); // false 注意:以上帶 [內容] 的規則都只能用于匹配單個字符// 2、預定義字符(只能匹配單個字符)  .  \d  \D   \s  \S  \w  \WSystem.out.println("徐".matches(".")); // .可以匹配任意字符System.out.println("徐徐".matches(".")); // false// \轉義System.out.println("\"");// \n \tSystem.out.println("3".matches("\\d"));  // \d: 0-9System.out.println("a".matches("\\d"));  //falseSystem.out.println(" ".matches("\\s"));   // \s: 代表一個空白字符System.out.println("a".matches("\s")); // falseSystem.out.println("a".matches("\\S"));  // \S: 代表一個非空白字符System.out.println(" ".matches("\\S")); // falseSystem.out.println("a".matches("\\w"));  // \w: [a-zA-Z_0-9]System.out.println("_".matches("\\w")); // trueSystem.out.println("徐".matches("\\w")); // falseSystem.out.println("徐".matches("\\W"));  // [^\w]不能是a-zA-Z_0-9System.out.println("a".matches("\\W"));  // falseSystem.out.println("23232".matches("\\d")); // false 注意:以上預定義字符都只能匹配單個字符。// 3、數量詞: ?   *   +   {n}   {n, }  {n, m}System.out.println("a".matches("\\w?"));   // ? 代表0次或1次System.out.println("".matches("\\w?"));    // trueSystem.out.println("abc".matches("\\w?")); // falseSystem.out.println("abc12".matches("\\w*"));   // * 代表0次或多次System.out.println("".matches("\\w*"));        // trueSystem.out.println("abc12張".matches("\\w*")); // falseSystem.out.println("abc12".matches("\\w+"));   // + 代表1次或多次System.out.println("".matches("\\w+"));       // falseSystem.out.println("abc12張".matches("\\w+")); // falseSystem.out.println("a3c".matches("\\w{3}"));   // {3} 代表要正好是n次System.out.println("abcd".matches("\\w{3}"));  // falseSystem.out.println("abcd".matches("\\w{3,}"));     // {3,} 代表是>=3次System.out.println("ab".matches("\\w{3,}"));     // falseSystem.out.println("abcde徐".matches("\\w{3,}"));     // falseSystem.out.println("abc232d".matches("\\w{3,9}"));     // {3, 9} 代表是  大于等于3次,小于等于9次// 4、其他幾個常用的符號:(?i)忽略大小寫 、 或:| 、  分組:()System.out.println("abc".matches("(?i)abc")); // trueSystem.out.println("ABC".matches("(?i)abc")); // trueSystem.out.println("aBc".matches("a((?i)b)c")); // trueSystem.out.println("ABc".matches("a((?i)b)c")); // false// 需求1:要求要么是3個小寫字母,要么是3個數字。System.out.println("abc".matches("[a-z]{3}|\\d{3}")); // trueSystem.out.println("ABC".matches("[a-z]{3}|\\d{3}")); // falseSystem.out.println("123".matches("[a-z]{3}|\\d{3}")); // trueSystem.out.println("A12".matches("[a-z]{3}|\\d{3}")); // false// 需求2:必須是”我愛“開頭,中間可以是至少一個”編程“,最后至少是1個”666“System.out.println("我愛編程編程666666".matches("我愛(編程)+(666)+"));System.out.println("我愛編程編程66666".matches("我愛(編程)+(666)+"));}
}

5.3 正則表達式應用案例

public class RegexTest3 {public static void main(String[] args) {checkPhone();}public static void checkPhone(){while (true) {System.out.println("請您輸入您的電話號碼(手機|座機): ");Scanner sc = new Scanner(System.in);String phone = sc.nextLine();// 18676769999  010-3424242424 0104644535if(phone.matches("(1[3-9]\\d{9})|(0\\d{2,7}-?[1-9]\\d{4,19})")){System.out.println("您輸入的號碼格式正確~~~");break;}else {System.out.println("您輸入的號碼格式不正確~~~");}}}
}

5.4 正則表達式信息爬取

接下來我們學習正則表達式的第二個作用:在一段文本中查找滿足要求的內容

public class RegexTest4 {public static void main(String[] args) {method1();}// 需求1:從以下內容中爬取出,手機,郵箱,座機、400電話等信息。public static void method1(){String data = " 來黑馬程序員學習Java,\n" +"        電話:1866668888,18699997777\n" +"        或者聯系郵箱:boniu@itcast.cn,\n" +"        座機電話:01036517895,010-98951256\n" +"        郵箱:bozai@itcast.cn,\n" +"        郵箱:dlei0009@163.com,\n" +"        熱線電話:400-618-9090 ,400-618-4000,4006184000,4006189090";// 1、定義爬取規則String regex = "(1[3-9]\\d{9})|(0\\d{2,7}-?[1-9]\\d{4,19})|(\\w{2,}@\\w{2,20}(\\.\\w{2,10}){1,2})"+ "|(400-?\\d{3,7}-?\\d{3,7})";// 2、把正則表達式封裝成一個Pattern對象Pattern pattern = Pattern.compile(regex);// 3、通過pattern對象去獲取查找內容的匹配器對象。Matcher matcher = pattern.matcher(data);// 4、定義一個循環開始爬取信息while (matcher.find()){String rs = matcher.group(); // 獲取到了找到的內容了。System.out.println(rs);}}
}

5.5 正則表達式搜索、替換

接下來,我們學習一下正則表達式的另外兩個功能,替換、分割的功能。需要注意的是這幾個功能需要用到Stirng類中的方法。這兩個方法其實我們之前學過,只是當時沒有學正則表達式而已。
在這里插入圖片描述

public class RegexTest5 {public static void main(String[] args) {// 1、public String replaceAll(String regex , String newStr):按照正則表達式匹配的內容進行替換// 需求1:請把下面字符串中的不是漢字的部分替換為 “-”String s1 = "古力娜扎ai8888迪麗熱巴999aa5566馬爾扎哈fbbfsfs42425卡爾扎巴";System.out.println(s1.replaceAll("\\w+", "-"));// 需求2(拓展):某語音系統,收到一個口吃的人說的“我我我喜歡編編編編編編編編編編編編程程程!”,需要優化成“我喜歡編程!”。String s2 = "我我我喜歡編編編編編編編編編編編編程程程";System.out.println(s2.replaceAll("(.)\\1+", "$1"));// 2、public String[] split(String regex):按照正則表達式匹配的內容進行分割字符串,反回一個字符串數組。// 需求1:請把下面字符串中的人名取出來,使用切割來做String s3 = "古力娜扎ai8888迪麗熱巴999aa5566馬爾扎哈fbbfsfs42425卡爾扎巴";String[] names = s3.split("\\w+");System.out.println(Arrays.toString(names));}
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/96915.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/96915.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/96915.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

K8s學習筆記(二) Pod入門與實戰

1 K8s核心資源Pod 1.1 Pod是什么&#xff1f; 官方文檔&#xff1a;Pod | Kubernetes Pod 是 Kubernetes&#xff08;k8s&#xff09;中最小的部署與調度單元&#xff0c;并非直接運行容器&#xff0c;而是對一個或多個 “緊密關聯” 容器的封裝。 核心特點可簡單總結為 3 …

用 Python 調用 Bright Data MCP Server:在 VS Code 中實現實時網頁數據抓取

用 Python 調用 Bright Data MCP Server&#xff1a;在 VS Code 中實現實時網頁數據抓取&#xff0c;本文介紹了Bright Data的Web MCP Server&#xff0c;這是一款能實現實時、結構化網頁數據訪問的API&#xff0c;適用于AI應用等場景。其支持靜態與動態網頁&#xff0c;前3個月…

SPSS繪制ROC曲線并計算靈敏度、特異度

SPSS繪制ROC曲線并計算靈敏度、特異度。 &#xff08;1&#xff09;繪制ROC曲線&#xff1a; 輸入&#xff1a;預測值、受試者標簽。 在SPSS中點擊“分析”-“分類”-“ROC曲線” 變量輸入&#xff1a;檢驗變量輸入預測值&#xff0c;狀態變量輸入受試者標簽&#xff0c;如果標…

Modbus協議原理與Go語言實現詳解

目錄 Modbus協議概述協議架構與通信模式Modbus數據模型Modbus協議幀格式功能碼詳解Go Modbus庫完整實現高級應用示例調試與故障排除 Modbus協議概述 Modbus是一種串行通信協議&#xff0c;由Modicon公司&#xff08;現施耐德電氣&#xff09;于1979年開發&#xff0c;用于PL…

下載CentOS 7——從阿里云上下載不同版本的 CentOS 7

沒有廢話&#xff0c;直接上干貨。跟著圖片教程&#xff0c;一步一步來就行。 想下載其它版本的&#xff0c;自己可以再選擇其它的就行。 想省事的朋友可以直接點擊: 1、下載頁面鏈接 2、CentOS-7-x86_64-DVD-2207-02(4.4GB).iso

SpringBoot -原理篇

文章目錄配置優先級Bean管理獲取beanbean作用域第三方beanSpringBoot原理起步依賴自動配置自動配置原理方案源碼跟蹤原理分析 Conditional案例&#xff08;自定義starter&#xff09;案例&#xff08;自定義starter分析&#xff09;案例&#xff08;自定義starter實現&#xff…

JavaScript與jQuery:從入門到面試的完整指南

JavaScript與jQuery&#xff1a;從入門到面試的完整指南 第一部分&#xff1a;JavaScript基礎 1.1 JavaScript簡介 JavaScript是一種輕量級的解釋型編程語言&#xff0c;主要用于Web開發&#xff0c;可以為網頁添加交互功能。它是ECMAScript規范的一種實現。 // 第一個JavaScri…

解決:Ubuntu、Kylin、Rocky系統中root用戶忘記密碼

解決Linux系統中root用戶忘記密碼 Ubuntu2204 重啟電腦&#xff0c;啟動時&#xff0c;長按Shift鍵&#xff08;對于 BIOS 系統&#xff09;或 Esc 鍵&#xff08;對于 UEFI 系統&#xff09;進入GRUB菜單 步驟1&#xff1a;重啟Ubuntu系統&#xff0c;長按Shift鍵進入Ubuntu…

ENVI系列教程(二)——自定義坐標系(北京 54、西安 80、2000 坐標系)

目錄 1 概述 1.1 地理投影的基本原理 1.2 國內坐標系介紹 1.3 參數的獲取 2 詳細操作步驟 2.1 添加橢球體 2.2 添加基準面 2.3 定義坐標系 2.4 使用自定義坐標系 1 概述 1.1 地理投影的基本原理 常用到的地圖坐標系有 2 種,即地理坐標系和投影坐標系。地理坐標系是…

一種基于因果干預的少樣本學習的故障診斷模型

一、研究背景與問題 ?工業背景?:機械故障診斷對工業系統安全至關重要,但實際中故障樣本稀少,難以訓練傳統深度學習模型。 ?現有問題?: 當前少樣本學習(FSL)方法大多基于相關性而非因果關系建模,容易學習到偽相關特征,導致模型可解釋性差、泛化能力弱。 跨組件故障診…

機器視覺光源的尺寸該如何選型的方法

機器視覺光源的尺寸該如何選型的方法&#x1f3af;機器視覺光源的尺寸選型的方法&#x1f3af;一、選型案例&#x1f3af;二、照射方式&#x1f3af;三、鏡頭選擇&#x1f3af;四、光源架構光源的工作距離與視野大小&#x1f3af;五、總結&#xff1a;光源選型 —— 機器視覺檢…

HTML新屬性

HTML5引入了許多新屬性&#xff0c;旨在增強語義化、交互性和多媒體支持。以下是一些重要的新屬性及其用途分類&#xff1a;語義化與結構屬性data-*&#xff1a;自定義數據屬性&#xff0c;允許開發者存儲額外信息&#xff08;如data-id"123"&#xff09;。hidden&am…

從工地到鏈上:一個土建人的 Web3 轉行經歷

Web3 的風&#xff0c;終究還是吹到了土建行業。2017 年&#xff0c;土建專業&#xff08;給排水工程&#xff09;的劉正源偶然看到一則關于比特幣的新聞&#xff0c;被它背后的經濟模型與技術架構深深震撼。到了 2021 年&#xff0c;他在工地上再次聽人提起區塊鏈&#xff0c;…

20250914-03: Langchain概念:提示模板+少樣本提示

20250914-03: Langchain概念&#xff1a;提示模板少樣本提示 聊天模型 消息 提示 結構化輸出 &#x1f3af; 學習目標 掌握如何“喂給模型正確的輸入”并“解析出想要的輸出”。 &#x1f517; 核心概念 ?聊天模型&#xff08;ChatModel&#xff09;?消息&#xff08;M…

【AI推理部署】Docker篇04—Docker自動構建鏡像

Docker 自動構建鏡像1. Dockfile 編寫2. 鏡像使用使用 Dockerfile 構建鏡像 Dockerfile 其實就是把我們前面的一系列安裝、配置命令寫到一個文件中&#xff0c;通過 docker build 命令&#xff0c;一鍵完成鏡像的構建。接下來&#xff0c;我們以 bitnami/pytorch:2.1.1 作為基礎…

LeetCode 674.最長連續遞增序列

給定一個未經排序的整數數組&#xff0c;找到最長且 連續遞增的子序列&#xff0c;并返回該序列的長度。 連續遞增的子序列 可以由兩個下標 l 和 r&#xff08;l < r&#xff09;確定&#xff0c;如果對于每個 l < i < r&#xff0c;都有 nums[i] < nums[i 1] &am…

貪心算法java

貪心算法簡介貪心算法是一種在每一步選擇中都采取在當前狀態下最優&#xff08;局部最優&#xff09;的選擇&#xff0c;從而希望導致結果是全局最優的算法。貪心算法通常用于解決最優化問題&#xff0c;如最短路徑、最小生成樹、任務調度等。貪心算法的基本步驟問題分析&#…

【華為OD】解鎖犯罪時間

【華為OD】解鎖犯罪時間 題目描述 警察在偵破一個案件時&#xff0c;得到了線人給出的可能犯罪時間&#xff0c;形如"HH:MM"表示的時刻。根據警察和線人的約定&#xff0c;為了隱蔽&#xff0c;該時間是修改過的&#xff0c;解密規則為&#xff1a;利用當前出現過的數…

基于linux操作系統的mysql安裝

一、檢查自己的操作系統是否已經有存在的mysql 1.存在 2.不存在 二、基于操作系統不存在mysql,找官方yum源 網址&#xff1a; Index of /232905https://repo.mysql.com/ 網站打開是這樣 看看自己的操作系統是哪個版本&#xff0c;再下載哪個版本&#xff0c;如果和我一樣裝…

如何用 Git Hook 和 CI 流水線為 FastAPI 項目保駕護航?

url: /posts/fc4ef84559e04693a620d0714cb30787/ title: 如何用Git Hook和CI流水線為FastAPI項目保駕護航? date: 2025-09-14T00:12:42+08:00 lastmod: 2025-09-14T00:12:42+08:00 author: cmdragon summary: 持續集成(CI)在FastAPI項目中通過頻繁合并代碼和自動驗證,確保…