Java 常用類及常用方法
介紹jdk
中的常用的類中常用的方法 , 包括:
- String
- StringBuffer
- 基礎類型對應的包裝類
- 日期相關類
- 數字相關類
- Random 隨機數
- Enum 枚舉類
String
類
String
類不能繼承,因爲它是使用 final 修飾的
public final class String ...
String
表面上是一個字符串,實際上底層是用一個字符數組存的;String
類是不可變類,也就是說String
對象聲明後,將不可修改
/** The value is used for character storage. */
private final char value[];
// 這個字符數組還是用 final 關鍵字修飾的,也是爲什麼String創建之後不可修改的原因
Java.lang.String; 是字符串類型
-
字符串一旦創建,不可以再改變
- 例如 “abc” 字符串對象一旦創建,就不能改變爲 “abcd”
-
由於在程序中字符串經常出現,所以爲了提升字符串的訪問效率,在程序中使用了**“緩存”**技術。即在Java中使用 **“ ”**括起來的字符串都會在 字符串常量池 中創建一份
-
字符串常量池在JVM 的方法區內存中存取
在程序執行過程中,如果程序中用到某一個字符串,例如 “abc”,那麼程序會首先在 字符串常量池 中去搜索這個字符串。如果沒有找到則在字符串常量池中新建一個 “abc” 字符串;如果找到了就直接拿來用。(字符串常量池是一個緩存區,是爲了提高字符串的訪問效率)
public class Test01 { public static void main(String[] args) { String s1 = "abc"; String s2 = "abc"; // == 比較的是兩個引用指向的內存空間 System.out.println(s1 == s2); // 輸出啥? // true String s3 = new String("bcd"); // 存儲在棧空間 String s4 = new String("bcd"); System.out.println(s3 == s4);// 輸出啥? // false System.out.println(s3.equals(s4)); // String 類中的 equals方法比較的是字符串的值 // 輸出 true // 以下程序執行會在字符串常量池中創建 3 個 字符串常量 // "aaa", "bbb", "aaabbb" // 所以在涉及到頻繁的字符串拼接的程序中,不推薦使用 直接字符串相+ String s5 = "aaa"; String s6 = "bbb"; String s7 = s5 + s6; } }
-
-
分析以下程序創建字符串對象的區別
public class Test02 { public static void main(String[] args) { String s1 = "abc"; String s2 = new String("abc"); } }
-
String s1 = “abc”; 只會在方法區中的 “字符串常量池” 中創建一個 “abc” 字符串對象
-
String s2 = new String(“bac”); 會在字符串常量池中創建一個 “bac” 字符串對象,並且會在 堆內存 中再創建一個字符串對象
第二種方式比較浪費內存,常用的是第一種方式
-
判斷以下程序中創建了幾個字符串對象
public class Test03 { public static void main(String[] args) { String s1 = new String("abc"); String s2 = new String("abc"); } }
- 創建了 3 個字符串對象
- 堆內存中創建 2 個
- 方法區內存中的 字符串常量池 中創建了 1 個
- 注意:
- 堆內存區中是運行時分配的
- 方法區內存區中的 字符串常量池 是 編譯時 分配的
- 創建了 3 個字符串對象
-
使用String類型的字符串時請注意不要進行字符串的頻繁拼接
- 字符串一旦創建就不可改變,頻繁拼接會在方法區內存的 字符串常量池 中創建大量的字符串對象,給垃圾回收帶來困難。
關於字符串中的常用方法:
-
常用的構造方法
public class Test04 { public static void main(String[] args) { // 1 String s1 = "abc"; // 2 String s2 = new String("abc"); // 3 byte[] bytes = {97, 98, 99, 100}; String s3 = new String(bytes); // abcd System.out.println(s3); // 4 String s4 = new String(bytes, 1, 3); // bcd System.out.println(s4); // 5 char[] chars = {'a', 'b','c', 'd', 'e'}; String s5 = new String(chars);// abcde System.out.println(s5); // 6 String s6 = new String(chars, 2, 2);// cd System.out.println(s6); } }
-
常用的方法
package com.test.classandmethod; public class Test05 { public static void main(String[] args) { //1. char charAt(int index) char c1 = "abcedfa".charAt(3); System.out.println(c1); // e //2. boolean endsWith(String suffix) System.out.println("HelloWorld.java".endsWith(".java")); // true //3. boolean equals(Object anObject) System.out.println("hello".equals(new String("hello"))); // true //4. boolean equalsIgnoreCase(String anotherString) System.out.println("hello".equalsIgnoreCase("Hello")); //5. byte[] getBytes() byte[] res = "hello".getBytes(); for(int i=0; i<res.length; i++) { System.out.print(res[i]+" "); // 104 101 108 108 111 } System.out.println(); //6. int indexOf(String str) int index = "jdhfadfa".indexOf("a"); System.out.println(index); // 4 //7. int indexOf(String str, int fromIndex) index = "jkdhkajlf".indexOf("j", 2); System.out.println(index); // 6 //8. int lastIndexOf(String str) index = "jdhfakljdhfap[qijkmdnv;kajkha".lastIndexOf("f"); System.out.println(index); // 10 //9. int lastIndexOf(String str, int fromIndex) // 從開始位置往前找 index = "jdhfakljdhfap[qijkmdnv;kajka".lastIndexOf("h", 6); System.out.println(index); // 2 //10. int length() System.out.println("hdgahdg".length());// 7 //11. String replaceAll(String regex, String replacement) String resS = "jkhaflkjhfdlakjdfha".replaceAll("d", "D"); System.out.println(resS);//jkhaflkjhfDlakjDfha //12. String[] split(String regex) String[] s1 = "jdhaflkjdhl,fmakdjfa.mafsdkfjak.sajdfhal.sdflajdfuq".split("f"); System.out.println(s1.length); for(int i=0; i<s1.length; i++) { System.out.println(s1[i]); } //13. boolean startsWith(String prefix) System.out.println("aafdsfads".startsWith("aa"));// true //14. String substring(int beginIndex); System.out.println("dhjfajdfha".substring(2)); // jfajdfha //15. String substring(int beginIndex, int endIndex) System.out.println("jahdjfa".substring(2, 5));//hdj //16. char[] toCharArray() char[] ch1 = "dkjhfaljkd".toCharArray(); for (int i = 0; i < ch1.length; i++) { System.out.print(ch1[i] + " "); //d k j h f a l j k d } System.out.println(); //17. String toLowerCase() System.out.println("JHDGFADF".toLowerCase()); //jhdgfadf System.out.println("jhdgfadf".toUpperCase()); //JHDGFADF //18. String trim() System.out.println(" ajdhflaj dhfaljkd dfhal ".trim()); //ajdhflaj dhfaljkd dfhal //19. static String valueOf(...) System.out.println(String.valueOf(true)); // true Object obj = null; System.out.println(obj); // 不會報錯 相當於調用了String.valueOf(obj) System.out.println(obj.toString()); // 空指針異常 } }
-
“正則表達式”
正則表達式是一種字符模型,專門做字符串格式匹配的。正則表達式是通用的。
-
例如:
"^a{2}$" // 表示 2 個 a 字符, 等同於 "aa" String 類中有一個matches方法: public boolean matches(String regex); 用於判斷正則表達式是否匹配給定的字符串;
-
一些表示:
\d 數字 \D 非數字 \w 英文字母 \W 非英文字母
public class Test06 { public static void main(String[] args) { String s1 = "jkdafa23j4ddeq32941aiuhdef89qy"; // 將 dd 替換爲 中 System.out.println(s1.replaceAll("dd", "中")); // 將 dd 替換爲 中 System.out.println(s1.replaceAll("d{2}", "中")); //將所有的 數字 替換爲 中 System.out.println(s1.replaceAll("\\d", "中")); //將所有的 非數字 替換爲 中 System.out.println(s1.replaceAll("\\D", "中")); System.out.println("aa".matches("^a{2}$")); // true System.out.println("ab".matches("^a{2}$")); // false } }
-
-
StringBuffer
和StringBuilder
java.lang.StringBuffer java.lang.StringBuilder
-
StringBuffer
和StringBuilder
是什麼?是一個字符串緩衝區
-
工作原理
預先再內存中申請一塊內存,以容納字符序列。如果預留的空間不夠用,則進行自動擴容,以容納更所字符序列
-
和
String
的最大區別- String 是不可變的字符序列,存儲在方法區的字符串常量池中
- StringBuffer和StringBuilder底層是一個char數組,但是這個 char 數組是可變的,並且可以自動擴容
-
StringBuffer 和 StringBuilder 的默認初始化容量是 16
-
如何優化 StringBuffer 和 StringBuilder 呢?
最好在創建 StringBuffer 和 StringBuilder 的時候預測他們存儲的字符數量,然後在創建 StringBuffer 和 創建 StringBuilder 的時候採用指定初始化容量的方法創建StringBuffer/StringBuilder, 從而實現減少底層數組的拷貝,提高效率。
-
在做字符串頻繁拼接的時候,建議使用 StringBuffer 和 StringBuilder
public class Test07 { public static void main(String[] args) { StringBuffer sb = new StringBuffer(20); String[] s = {"運動","休閒","娛樂","工作"}; for(int i=0; i<s.length; i++) { if(i == s.length-1) { sb.append(s[i]); }else { sb.append(s[i]); sb.append(","); } } System.out.println(sb); } }
-
Stringbuffer 和 StringBuilder 之間的區別:
- StringBuffer是線程安全
- 在多線程環境下使用不會出現問題
- StringBuilder 是非線程安全的
- 在多線程環境中使用可能會出現問題
- StringBuffer是線程安全
-
基本數據類行對應的包裝類型
基本數據類型 | 包裝類型 |
---|---|
byte | java.lang.Byte; |
short | java.lang.Short; |
int | java.lang.Integer; |
long | java.lang.Long; |
float | java.lang.Float; |
double | java.lang.Double; |
boolean | java.lang.Boolean; |
char | java.lang.Character; |
-
已經有基本數據類型了,爲什麼還要提供包裝類?
爲了方便
public class Test08 { public static void main(String[] args) { // 基本數據類型 byte b = 10; // 引用數據類型 Byte b1 = new Byte(b); m1(b1); // 10 Byte類已經將Object類中的 toString類重寫 // 備註: 其實可以直接傳進去 10, 涉及到自動裝箱, 自動拆箱 } // 需求: 規定m1方法可以接收任何一種數據類型 // m1方法如果想接收byte類型的數據的時候,可以先將byte類型包裝成 java.lang.Byte; 再傳遞參數 private static void m1(Object obj) { System.out.println(obj); } }
-
包裝類的繼承結構圖
-
常用的包裝類及常用的方法 ---- 以
java.lang.Integer
爲例:-
構造方法
public class Test09 { public static void main(String[] args) { // 獲取 integer 的最大值最小值 System.out.println(Integer.MAX_VALUE); System.out.println(Integer.MIN_VALUE); // 獲取 Byte的最大值最小值 System.out.println(Byte.MAX_VALUE); System.out.println(Byte.MIN_VALUE); // 創建Integer類型的對象 Integer i1 = new Integer(11); // int --> Integer Integer i2 = new Integer("123"); // String ---> Integer System.out.println(i1); System.out.println(i2); // 一下程序編譯可以通過,但是運行的時候會報異常 // 雖然可以將字符串轉換成 Integer 類型,但是該字符串也應該是 "數字字符串" // Integer i3 = new Integer("abc");//java.lang.NumberFormatException } }
-
常用方法
-
integer 常用方法
public class Test10 { public static void main(String[] args) { // intValue, byteValue, floatValue, doubleValue, longValue // int --> Integer Integer i1 = new Integer(10); // String --> Integer Integer i3 = new Integer("132"); // Integer --> int // 引用類型 --> 基本類型 int i2 = i1.intValue(); System.out.println(i2+1); // 11 // 重要:static int parseInt(String s) // String --> int int i4 = Integer.parseInt("4321");// 裏面的字符串必須是“數字字符串” System.out.println(i4+1);//4322 // 重要: static double parseDouble(String s) // String --> double double d1 = Double.parseDouble("3.14"); System.out.println(d1);//3.14 // static String toBinaryString(int i) // static String toHexString(int i) // static String toOctalString(int i); int i5 = 324; String s1 = Integer.toBinaryString(i5);//101000100 System.out.println(s1); String s2 = Integer.toHexString(i5);//144 System.out.println(s2); String s3 = Integer.toOctalString(i5);//504 System.out.println(s3); } }
-
三種類型相互轉換
/** * 三種類型相互轉換 * Integer * String * int * */ public class Test11 { public static void main(String[] args) { // 1. int --> Integer Integer i1 = Integer.valueOf(10); // 2. Integer --> int int i2 = i1.intValue(); // 3. String --> Integer Integer i3 = Integer.valueOf("123"); // 4. Integer --> String String s1 = i3.toString(); // 5. String --> int int i4 = Integer.parseInt("123"); // 6. int --> String String s2 = 12 + ""; } }
-
-
-
自動裝箱和自動拆箱
-
自動裝箱 auto_boxing
-
自動拆箱 auto_unboxing
/** * 自動裝箱 * auto_boxing * 自動拆箱 * auto_unboxing * */ public class Test12 { public static void main(String[] args) { //1. // int --> Integer Integer i1 = new Integer(10); // 裝箱 // Integer --> int int i2 = i1.intValue(); // 拆箱 //2. // int --> Integer Integer i3 = 10; // 自動裝箱 // Integer --> int int i4 = i3; // 自動拆箱 m2(10, 5); // 自動裝箱 } public static Integer m2(Integer i1, Integer i2) { return i1 - i2; // 存在自動拆箱,自動裝箱 } }
-
深入自動裝箱,自動拆箱
-
自動裝箱 和 自動拆箱 是 程序編譯階段的概念,與程序運行無關。
-
自動裝箱 和 自動拆箱 的主要目的是方便程序員的編碼
-
整型常量池:
-
像方法區中的“字符串常量池”一樣,java爲**[-128, 127]之間的整數在方法區內存中建立了一個“整型常量池“**
-
該整型常量池只存儲【-128, 127】之間的數,每個數都對應放在方法區內存空間
Integer i7 = 127;
這行代碼就會直接從方法區整型常量池中尋找 127 存儲的內存地址,直接給 i7;不會在堆中創建對象
-
整型常量池中的數據 在 Integer 類加載後就創建了
-
public class Test13 { public static void main(String[] args) { Integer i1 = new Integer(10);// 會在堆中創建對象 Integer i2 = new Integer(10); System.out.println(i1 == i2);// false 這裏不會出現自動拆箱 // 比較兩個Integer類型的數據是否相等,不能用 “==” // Integer 已經重寫了 Object中的 equals 方法 System.out.println(i1.equals(i2)); // true // 重點 Integer i3 = 128; Integer i4 = 128; //上面兩行代碼等價於 Integer i5 = new Integer(128); Integer i6 = new Integer(128);// 發生了自動裝箱 System.out.println(i3 == i4); // false // 注意以下代碼(面試常考) Integer i7 = 127; // 不會在堆中創建對象,會直接從整型常量池中拿 Integer i8 = 127; // 不會在堆中創建對象,會直接從整型常量池中拿 System.out.println(i7 == i8);// true Integer i9 = -128; Integer i10 = -128; System.out.println(i9 == i10);// true Integer i11 = -129; Integer i12 = -129; System.out.println(i11 == i12); // false // 爲什麼會出現這種情況呢? // 如果數據在 [-128, 127] 之間,java中引入了一個"整型常量池"(在方法區內存中) // 該整型常量池只存儲 [-128, 127]之間的數據(在類加載後就會創建,對應代碼放在靜態代碼區) } }
-
-
日期類型
-
獲取毫秒數
/** * 獲取自 1970年1月1日0時0分0秒000毫秒到當前的毫秒數 * 1000 毫秒 = 1 秒 * java.lang * System Class * currentTimeMillis() */ public class Test14 { public static void main(String[] args) { // static long currentTimeMillis() long now = System.currentTimeMillis(); System.out.println(now); // 1583735040606 } }
-
日期格式化
import java.util.Date; import java.text.SimpleDateFormat; public class Test15 { public static void main(String[] args) { // 獲取系統當前的時間 Date now = new Date(); System.out.println(now);// Mon Mar 09 14:47:44 CST 2020 // 如何定製日期的輸出格式呢? // 引入格式化日期 // java.util.Date --> String // java.text.SimpleDateFormat SimpleDateFormat sdf = new SimpleDateFormat(); String sdfNow = sdf.format(now); System.out.println(sdfNow); // 20-3-9 下午2:55 sdf = new SimpleDateFormat("yyyy-MM-dd:HH-mm-ss-SSS"); sdfNow = sdf.format(now); System.out.println(sdfNow);// 2020-03-09:14-56-54-987 sdf = new SimpleDateFormat("yyyy年MM月dd日:HH時mm分ss秒SSS毫秒"); sdfNow = sdf.format(now); System.out.println(sdfNow);// 2020年03月09日:14時57分44秒278毫秒 } }
-
常用的日期格式
日期格式:
y 年
M 月
d 日
H 時
m 分
s 秒
S 毫秒
-
獲取特定的日期
- 上面獲取的是系統當前的日期
import java.util.Date; import java.text.ParseException;// 直接繼承 Exception類,是編譯型異常 import java.text.SimpleDateFormat; public class test16 { public static void main(String[] args) throws ParseException { // 獲取特定時刻的日期 String strTime = "2008年8月8日 08:08:08 888"; // 將String類型的日期轉換成日期類型Date的日期 // String --> Date //1. 創建日期格式化對象 SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss SSS"); //格式不能隨意,應該和上面的字符串格式相同 //2. 將字符串轉換成日期類型 Date date = sdf.parse(strTime);// 需要處理編譯型異常 System.out.println(date);// Fri Aug 08 08:08:08 CST 2008 } }
-
獲取當前時間的前10分鐘的時間
import java.text.SimpleDateFormat; import java.util.Date; /* Date date = new Date();// 獲取系統當前時間 Date date = new Date(long date); date - the milliseconds since January 1, 1970, 00:00:00 GMT. */ public class Test17 { public static void main(String[] args) { Date t1 = new Date(1000); // Date --> String SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS"); String s1 = sdf.format(t1); // 在北京東八區,所以是8點 System.out.println(s1); //1970-01-01 08:00:01 000 // 獲取當前系統時間的前10分鐘的時間 // 2020-03-09 16:01:38 175 // 2020-03-09 16:11:38 175 Date t2 = new Date(System.currentTimeMillis()- 1000*60*10); System.out.println(sdf.format(t2)); System.out.println(sdf.format(new Date())); } }
-
-
java.util.Calendar
日曆
import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; /** * 日曆 * java.util.Calendar * */ public class Test18 { public static void main(String[] args) throws ParseException { // 獲取系統的當前日曆 // static Calendar getInstance() // Gets a calendar using the default time zone and locale. Calendar c = Calendar.getInstance(); // 查看當前日曆的星期幾 // int get(int field) int i = c.get(Calendar.DAY_OF_WEEK);// 中國人的星期日,外國人看作第一天 System.out.println(i);// 2 // 查看當前日曆的day i = c.get(Calendar.DAY_OF_MONTH); System.out.println(i);// 9 // 獲取 2008年8月8日是星期幾 // void setTime(Date date) // Sets this Calendar's time with the given Date. // 1. 獲取2008年8月8日的日期 String-->Date String str = "2008年08月08日"; SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日"); Date date = sdf.parse(str); // 2. 創建該日期對應的日曆 c.setTime(date); // 3. 獲取星期幾 System.out.println(c.get(Calendar.DAY_OF_WEEK));//6 } }
數字類
-
關於數字格式化
java.text.DecimalFormat
數字格式元素:
# 任意數字 , 千分位 . 小數點 0 不夠補零
/** * 數字格式化 */ import java.text.DecimalFormat; public class Test19 { public static void main(String[] args) { // 1. 創建數字格式化對象, 加入千分位 DecimalFormat df = new DecimalFormat("###,###");// 1,234,567 // 2. 開始格式化 // Number --> String System.out.println(df.format(1234567)); // 加入千分位,保留兩位小數 df = new DecimalFormat("###,###.##"); System.out.println(df.format(123456.234));// 123,456.23 // 加入千分位,保留4位小數,不夠補零 df = new DecimalFormat("###,###.0000"); System.out.println(df.format(1233432.23));// 1,233,432.2300 } }
-
java.math.bigDecimal;
-
該類型的數據精確度極高,適合做財務軟件
-
double 類型的精度對於財務處理來說太低
import java.math.BigDecimal; public class Test20 { public static void main(String[] args) { // 創建大數據 BigDecimal v1 = new BigDecimal(10); BigDecimal v2 = new BigDecimal(20); //做加法運算 // v1+v2 // 錯誤,兩個引用類型不能做加法運算 BigDecimal v3 = v1.add(v2); System.out.println(v3); // 30 } }
-
隨機數
Random 位於 java.util 包下,可以產生隨機數
import java.util.Random;
public class Test21 {
public static void main(String[] args) {
// 創建一個新的隨機數生成器
Random random = new Random();
// 生成 int 類型的隨機數
int i = random.nextInt(101); //生成[0,101)之間的隨機數
System.out.println(i);
double d = random.nextDouble();
System.out.println(d);
}
}
枚舉類型: Enum
// 枚舉類型
public class Test22 {
public static void main(String[] args) {
int a = 10;
int b = 0;
Result resValue = m1(a, b);
if(Result.SUCCESS == resValue) {
System.out.println("成功");
}else {
System.out.println("失敗");
}
}
// 實現兩個數相乘,如果成功,返回0, 如果失敗,返回1
private static Result m1(int a, int b) {
try {
int res = a/b;
return Result.SUCCESS;
} catch (Exception e) {
return Result.FAIL;
}
}
}
// 定義枚舉類型
enum Result{
// 枚舉類型中的成員建議大寫
SUCCESS,
FAIL
}