包裝類Wrapper
- 針對八種基本資料型別相應的引用型別——包裝類
- 有了類的特點,可以呼叫類的方法
基本資料型別 | 包裝類 |
boolean | Booblean |
char | Character |
byte | Byte |
short | Short |
int | Integer |
long | Long |
float | Float |
double | Double |
注:Object是所有類的父類,關係圖中隱藏該父類
基本資料型別boolean對於的包裝類關係圖
基本資料型別char對應的包裝類關係圖
各數值型別對應包裝類關係圖
包裝類和基本資料型別的轉換
- 裝箱:基本型別轉包裝型別;反之為拆箱。
- 自jdk5以後的自定裝箱和拆箱方式
- 自動裝箱底層呼叫valueOf方法,如:Integer.valueOf()
public class Integer01 {
public static void main(String[] args) {
// jdk5以前
// 手動裝箱示範:int->Integer
int num=10;
Integer integer=new Integer(num);
Integer integer1=Integer.valueOf(num);
//手動拆箱
int i=integer.intValue();
// 自動裝箱
int num2=20;
Integer integer2=num2; // 底層用的是Integer.valueOf(num2)
// 自動拆箱
int num3=integer2; // 底層任然使用intValue()方法
}
}
其他包裝類的用法同理
包裝類和String型別的相互轉換
Integer和String
public class Wrapper {
public static void main(String[] args) {
// 方法一、包裝類Integer轉為String
Integer i=10; // 自動裝箱
// 以i為基本數值轉成str1,對i的原數值沒有影響
String str1=i+"";
// 方法二
String str2 = i.toString();
// 方法三
String str3 = String.valueOf(i);
String str4="123456";
// String->包裝類(Integer)
Integer.parseInt(str4);
Integer i2=Integer.parseInt(str4);// 自動裝箱
Integer i3=new Integer(str4); // 構造器
}
}
包裝類方法
Integer類和Character類的常用方法。其他方法需要使用時自行查詢。
public class Wrapper {
public static void main(String[] args) {
System.out.println(Integer.MIN_VALUE); //返回最小值
System.out.println(Integer.MAX_VALUE);//返回最大值
System.out.println(Character.isDigit('a'));//判斷是不是數字
System.out.println(Character.isLetter('a'));//判斷是不是字母
System.out.println(Character.isUpperCase('a'));//判斷是不是大寫
System.out.println(Character.isLowerCase('a'));//判斷是不是小寫
System.out.println(Character.isWhitespace('a'));//判斷是不是空格
System.out.println(Character.toUpperCase('a'));//轉成大寫
System.out.println(Character.toLowerCase('A'));//轉成小寫
}
}
String
- String物件用於儲存字串,也就是一組字元序列
- 字串常量物件是用雙引號括起的字元序列。例如:"hello"。
- 字串的字元使用Unicode字元編碼,一個字元佔兩個位元組(不區分字母還是漢字)。
- String類常用的構造方法
String s1=new String();
String s2=new String(String original);
String s3=new String(char[] a);
String s1=new String(char a,int starIndex,int count);
String類圖結構
- String實現了Serializable介面,說明String可以序列化;可以在網路上傳輸。
- Sting實現了Comparable介面,說明String可以比較。
- String是final類;不能被繼承。
- String有屬性 private final char value[];用於存放字串內容,value是一個final型別,地址不可修改(value不能指向新地址,但是單個字元內容可修改)。
public class Str {
public static void main(String[] args) {
String s = "rick";
final char[] value = {'a', 'b', 'c'};
char[] value2 = {'d', 'e', 'f'};
// value=value2; final約束不可以修改value地址
value[0] = 'B';
for (int i = 0; i < value.length; i++)
System.out.println(value[i]);
}
}
建立String物件的兩種方式
- 方式一,直接賦值:
String s="hello";
- 方式二,呼叫構造器:
String s2=new String("hello");
- 方式一:先從常量池檢視是否有"hello"資料空間,如果有,直接指向;沒有則重新建立然後指向。s最終指向常量池的空間地址。
- 方式二:先在堆中建立空間,裡面維護value屬性,指向常量池的hello空間。如果常量池沒有"hello",重新建立,有則直接透過value指向。最終指向的是堆中的空間地址。
建立String物件兩種方式的記憶體佈局圖
呼叫intern方法時如果池中已經包含一個等於此String物件的字串(用equals(Object)方法確定)。則返回池中字串,否則,把String物件的字串新增到池中,並返回物件的引用。
public class _Str {
public static void main(String[] args) {
String s1 = "hello";
String s2 = new String("hello");
System.out.println(s1.equals(s2));
System.out.println(s1 == s2.intern()); // s2.intern最終返回的是常量池中的常量池地址
System.out.println(s1 == s2);
}
}
String記憶體佈局示範程式碼(根據程式碼畫出記憶體佈局圖掌握記憶體佈局)
public class _Str {
public static void main(String[] args) {
Person person = new Person();
person.name="rick";
Person person1 = new Person();
person1.name="rick";
System.out.println(person.name.equals(person1.name));
System.out.println(person==person1);
System.out.println(person.name=="rick");
String s1=new String("hi");
String s2=new String("hi");
System.out.println(s1==s2);
}
}
class Person{
public String name;
}
字串的特性
public class _Str {
public static void main(String[] args) {
String s1="hi"+"rick"; // 編譯器會最佳化為[String s1="hirick";]所以會建立一個物件
String s2="ab";
String s3="cd";
String s4=s2+s3; //執行步驟:
// 1.建立一個StingBuilder s=new StringBuilder()
// 2.執行s.append("ab");
// 3.執行s.append("cd");
// 4.執行String s4 = s.toString();
// 最終s4指向堆中的物件(String)value[]->常量池中的"abcd"
String s5="abcd";
System.out.println(s4==s5);
System.out.println(s4.equals(s5));
T t = new T();
t.chage(t.str0, t.ch);
System.out.println(t.str0);
System.out.println(t.ch);
}
}
class T {
String str0 = new String("hello");
final char[] ch = {'j', 'a', 'v', 'a'};
public void chage(String str,char ch[]) {
str0 = "java";
ch[0] = 'N';
}
}
String的常用方法
String類是儲存字串常量的。每次更新都需要重新開闢空間,效率低,所以java設計者提供了StringBuffter和StringBuild增強String的功能,並提高效率。
String常用方法
public class _StrMethod {
public static void main(String[] args) {
String str1 = "hello";
String str2 = "Hello";
System.out.println(str1.equals(str2));//比較兩個字串內容
// 2.equalsIgnoreCase 忽略大小寫的判斷內容是否相等
String username = "johN";
if ("john".equalsIgnoreCase(username)) {
System.out.println("Success!");
} else {
System.out.println("Failure!");
}
// 3.length 獲取字元的個數,字串的長度
System.out.println("Jack三".length());
// 4.indexOf 獲取字元在字串物件中第一次出現的索引,索引從 0 開始,如果找不到,返回-1
String s1 = "wer@terwe@g";
int index = s1.indexOf('@');
System.out.println(index);// 3
System.out.println("weIndex=" + s1.indexOf("we"));//0
// 5.lastIndexOf 獲取字元在字串中最後一次出現的索引,索引從 0 開始,如果找不到,返回-1
s1 = "wer@terwe@g@";
index = s1.lastIndexOf('@');
System.out.println(index);//11
System.out.println("ter 的位置=" + s1.lastIndexOf("ter"));//4
// 6.substring 擷取指定範圍的子串
String name = "hello,張三";
//下面 name.substring(6) 從索引 6 開始擷取後面所有的內容
System.out.println(name.substring(6));//擷取後面的字元
//name.substring(0,5)表示從索引 0 開始擷取,擷取到索引 5-1=4的位置
System.out.println(name.substring(0, 5));//hllo
// 1.toUpperCase 把字串內字母全部轉換成大寫
String s2 = "HEllo";
System.out.println(s2.toUpperCase());
// 2.toLowerCase 把字串內所有字元轉為小寫
System.out.println(s2.toLowerCase());
String s3 = "jack";
//
s3 = s3.concat("hello").concat("every").concat("day");
System.out.println(s3);
s3 = "jackhelloeveryday";
// replace 把s3中所有hello 換成Hi,注意方法只對返回的結果處理,對原資料沒有影響
s3 = s3.replace("hello", "Hi");
System.out.println(s3);
String s4 = "Aa,Bb,Cc,Dd,Ee";
// 以 , 為標準進行分割返回一個陣列
String[] split = s4.split(",");
System.out.println("逗號分隔開的單個資料分別是:");
for (int i = 0; i < split.length; i++) {
System.out.println(split[i]);
}
String s5 = "hello";
// toCharArray 把字串轉為字元陣列
char[] chars0 = s5.toCharArray();
for (int i = 0; i < chars0.length; i++) {
System.out.println(chars0[i]);
}
// compareTo 比較兩個字串大小前者大返回正數否則為負相等為0
// 1.長度相同,每個字元相同返回0 2.長度相同或不同,比較時可以區分大小寫就返回s6-s7(具體檢視原始碼)3.前面部分相同就s6.length-s7.length
String s6 = "rick";
String s7 = "jack";
System.out.println(s6.compareTo(s7));// 返回 s7-s6的值
String name1="tom";
int age=18;
double score=97.5/3;
char gender='男';
String show="姓名"+name1+"年齡"+age+"平均成績"+score+"性別"+gender;
System.out.println(show);
// %s,%d 等這些叫做佔位符,由後面的變數來替換,佔位符具體用法檢視C語言
String info=String.format("年齡%s年齡%d平均成績%.2f性別:%c",name1,age,score,gender);
System.out.println(info);
}
}
其他方法透過jdk api 1.8_google文件檢視
StringBuffer類
java.lang.StrinngBuffer代表可變的字元序列,可以對字串內容進行增刪。很多方法與String相同,但StringBuffer是可變長度的。
- StrinngBuffer直接父類是AbstractStringBuilder
- StringBuffer實現了Serializable,即StringBuffer的物件可以序列
- 在父類AbstractStringBuilder中有屬性char[] value,不是final。
- 該value陣列存放字串內容,所以存放在堆中(不是常量池)。
- StringBuffer是一個final類。
String對比StringBuffer
- String儲存的是字串常量,裡面的值不能修改,String每次更新實際上是更新地址效率低(本質原因是
private final char value[];
) - StringBuffer儲存的是字串變數,裡面的值可以修改,且修改內容不用每次更新地址效率高(
char value[];
存放在堆中)
StringBuffer構造器
StringBuffer構造器
public class Buffer {
public static void main(String[] args) {
StringBuffer stringBuffer = new StringBuffer(); // 建立一個大小為16的char[],用於存放字元內容
StringBuffer stringBuffer2 = new StringBuffer(100); // 指定建立一個大小為100的char[]。
StringBuffer hello = new StringBuffer("hello"); // 透過給String建立一個StringBuffer,char[]大小就是一個str.length+16
}
}
String和StringBuffer的相互轉換
檢視程式碼
public class StringAndBuffer {
public static void main(String[] args) {
// String轉為StringBuffer
String str="hi rick";
// 使用構造器轉換
StringBuffer stringBuffer = new StringBuffer(str); //返回的才是StringBuffer物件對String本身沒有影響
// 使用append方法
StringBuffer stringBuffer1 = new StringBuffer();
stringBuffer1= stringBuffer1.append(str);
// StringBuffer轉String
StringBuffer stringBuffer2 = new StringBuffer("hello,jack");
// 使用StringBuffer提供的toString方法直接轉換
String s = stringBuffer2.toString();
// 使用構造器
String s1 = new String(stringBuffer2);
}
}
StringBuilder類
是一個可變的字元序列,此類提供一個與StringBuffer相容的API,但是不保證同步(StringBuilder存在多執行緒問題)。該類被設計用於StringBuffer的簡易替換,用在字串緩衝區被單個執行緒使用時。如果可能,建議優先採用該類,因為多數情況下,他比StringBuffer更快。
- 透過繼承關係圖得知StringBuilder繼承了AbstractStringBuilder類
- 實現了Serializable,說明StringBuilder物件是可以序列化(該物件可以網路傳輸,也可以儲存到檔案)同時還是final類
- StringBuilder物件字元依舊存放在其父類AbstractStringBuilder類,所以字元序列存放在堆中
- StringBuild的方法,沒有做互斥處理(沒有synchronized關鍵字,因此推薦在多執行緒的情況下使用)
在StringBuilder上的主要操作是append和insert方法,可過載這些方法,以接受任意型別。
String、StringBuilder、StringBuffer的比較
- StringBuilder和StringBuffer非常類似均代表可變的字元序列,且方法一樣。
- String:不可變字元序列,效率低、但是程式碼複用率高
- StringBuffer:可變字元序列,增刪效率較高、執行緒安全(原始碼可以看到方法被
synchronized
修飾)。 - StringBuffer:可變字元序列,效率最高、執行緒不安全。
String s="a"; // 建立了一個字串
s+="b"; // 實際上原來的“a”物件已經丟棄,現在產生新字串s+"b"("ab")
//如果多次執行(迴圈)這些改變字串操作會導致大量字串物件存留在記憶體中,降低效率
System.out.println("結論:如果這樣的操作放在迴圈中會極大地影響效能,所以對String做大量修改時,不要用String而是StringBuffer。");
使用總結:
- 如果字串存在大量修改操作,通常使用StringBuffer(多執行緒)或StringBuilder(單執行緒)
- 如果修改字串操作較少,被多個物件引用,使用String,如配置資訊等
Math類
基本介紹:包含用於基本數學運算的方法(均為靜態方法),例如初等指數,對數、平方根、三角函式。
Math常用方法
public class MathMethod {
public static void main(String[] args) {
System.out.println("Math常用的方法");
//看看 Math 常用的方法(靜態方法)
//1.abs 絕對值
int abs = Math.abs(-9);
System.out.println(abs);//9
//2.pow 求冪
double pow = Math.pow(2, 4);//2 的 4 次方
System.out.println(pow);//16.0
//3.ceil 向上取整,返回>=該引數的最小整數(轉成 double);
double ceil = Math.ceil(3.9);
System.out.println(ceil); //4.0
//4.floor 向下取整,返回<=該引數的最大整數(轉成 double)
double floor = Math.floor(4.001);
System.out.println(floor);//4.0
//5.round 四捨五入 Math.floor(該引數+0.5)
long round = Math.round(5.51);
System.out.println(round);//6
//6.sqrt 求開方
double sqrt = Math.sqrt(9.0);
System.out.println(sqrt);//3.0
//7.random 求隨機數
// random 返回的是 0 <= x < 1 之間的一個隨機小數
// a=2,b=7,=> (int)(a+Math.random()*(b-a+1))=(int)(2+Math.random()*6)
for (int i = 0; i < 100; i++) {
System.out.print((int) (2 + Math.random() * (7 - 2 + 1))+" ");
}
System.out.println("\n獲取a-b之間的隨機整數公式:int number=(int)(Math.random()*(b-a+1)+a)");
//max , min 返回最大值和最小值
int min = Math.min(1, 9);
int max = Math.max(45, 90);
System.out.println("\nmin=" + min);
System.out.println("max=" + max);
}
}
Array類
public class ArrayMethod {
public static void main(String[] args) {
Integer[] integers = {1, 2, 3};
// 遍歷陣列
/*for (int i = 0; i < integers.length; i++) {
System.out.println(integers[i]);
}*/
// 直接使用Array.toString方法,顯示陣列
System.out.println(Arrays.toString(integers)); // 檢視toString(選中【Ctrl】+【b】)方法可以知道返回的內容
Integer arr[] = {-1, 2, -3, 4, 5, -6, 7, 0};
// 進行排序 1、可以使用氣泡排序,也可以直接使用Array.sort方法直接排序
Arrays.sort(arr); // 預設排序;因為陣列是引用型別傳入的是地址排序後會修改實參arr
Arrays.sort(arr, new Comparator() { // 呼叫定製排序時,傳入兩個引數1.排序陣列arr,2.實現Comparator()介面的匿名內部類
// 原始碼分析1、Array.sort(arr,new Comparator())
// 2、最終到 TimSort的 private static <T> void binarySort(T[] a, int lo, int hi, int start,
// Comparator<? super T> c) ()
// 3、執行到binarySort方法的程式碼,會根據動態繫結機制c.compare()執行傳入的匿名內部類的compare()
// while (left < right) {
// int mid = (left + right) >>> 1;
// if (c.compare(pivot, a[mid]) < 0)
// right = mid;
// else
// left = mid + 1;
// }
// 4、執行傳入的匿名內部類
// 5、 public int compare(Object o1, Object o2) 返回的值>0還是<0 會影響整個排序的結果
@Override
public int compare(Object o1, Object o2) { // 要求實現compare方法
Integer i1 = (Integer) o1;
Integer i2 = (Integer) o2;
return i1-i2; // 從小到大;體現介面程式設計的方式(對匿名內部類下斷點除錯)
// return i2-i1;
}
});
// sort是過載的也可以透過傳入一個Comparator實現定製排序
System.out.println(Arrays.toString(arr));
}
}
檢視程式碼
public class ArrayCustomSort {
public static void main(String[] args) {
int arr[] = {0, -1, 2, 3, -5, -10};
bubble1(arr);
System.out.println("氣泡排序後");
System.out.println(Arrays.toString(arr));
bubble2(arr, new Comparator() {
@Override
public int compare(Object o1, Object o2) {
int i1 = (Integer) o1; //拆箱
int i2 = (Integer) o2;
// return i1 - i2; // 小到大
return i2-i1; //大到小
}
});
System.out.println("自定義排序後:"+Arrays.toString(arr));
}
// 氣泡排序
public static void bubble1(int arr[]) {
int temp = 0;
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr.length - 1 - i; j++) {
if (arr[j] > arr[j + 1]) { // 從小到大
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
}
// 改進
public static void bubble2(int[] arr, Comparator comparator) {
int temp = 0;
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr.length - 1 - i; j++) {
// 陣列的排序由comparator.compare(arr[j], arr[j + 1])返回的值決定
if (comparator.compare(arr[j], arr[j + 1]) > 0) {
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
}
}
二分查詢
public class ArrayMethod {
public static void main(String[] args) {
// binarySearch透過二分查詢,要求必須是排序好(有序的)的陣列
Integer[] arr = {-1,0,1,2,3,4,6,8,10};
int index=Arrays.binarySearch(arr,10);
System.out.println(index); // 陣列不存在查詢的元素則返回return -(low + 1); low指查詢元素應該存在的位置
}
}
Array常用類
public class ArrayMethod {
public static void main(String[] args) {
// binarySearch透過二分查詢,要求必須是排序好(有序的)的陣列
Integer[] arr = {-1,0,1,2,3,4,6,8,10};
int index=Arrays.binarySearch(arr,10);
System.out.println(index); // 陣列不存在查詢的元素則返回return -(low + 1); low指查詢元素應該存在的位置
// copyOf 陣列元素複製:從arr陣列中複製arr.length個元素到newArr陣列中。
// 複製的長度大於arr.length,超出部分新增null,複製長度小於0丟擲異常
// 底層使用System.arraycopy()
Integer[] newArr=Arrays.copyOf(arr,arr.length);
System.out.println("複製的陣列:"+Arrays.toString(newArr));
// ill陣列元素填充
Integer num[]=new Integer[]{77,177,777};
// 用99填充num陣列換言之用99替換所有原來的元素
Arrays.fill(num,99);
System.out.println("陣列填充後:"+Arrays.toString(num));
// equals 比較兩個陣列是否完全一致
Integer[] arr2 = {-1,0,1,2,3,4,6,8,10};
// 如果arr和arr2陣列元素一樣返回true
// 如果不完全一樣返回false
boolean equals=Arrays.equals(arr,arr2);
System.out.println(equals);
// asList把一組值轉為list
// asList方法,會把(2,3,4,5,8,-1,0)資料轉為一個集合
// 返回的asList變異型別List介面
// asList執行型別是Array類的靜態內部類:private static class ArrayList<E> extends AbstractList<E>
// implements RandomAccess, java.io.Serializable
List<Integer>asList=Arrays.asList(2,3,4,5,8,-1,0);
System.out.println("aslist="+asList);
System.out.println("asList的執行型別是"+asList.getClass());
}
}
Array應用練習
public class ArrayMethod {
public static void main(String[] args) {
Book[] books = new Book[4];
books[0] = new Book("01", 100);
books[1] = new Book("002", 200);
books[2] = new Book("0003", 300);
books[3] = new Book("00004", 400);
//price從小到大
Arrays.sort(books, new Comparator<Book>() {
@Override
public int compare(Book o1, Book o2) {
Book book1 = (Book) o1;
Book book2 = (Book) o2;
double val = book2.getPrice() - book1.getPrice();
if (val > 0) {
return -1;
} else if (val < 0) {
return 1;
} else {
return 0;
}
}
});
System.out.println(Arrays.toString(books));
//price從大到小
Arrays.sort(books, new Comparator<Book>() {
@Override
public int compare(Book o1, Book o2) {
Book book1 = (Book) o1;
Book book2 = (Book) o2;
double val = book2.getPrice() - book1.getPrice();
if (val > 0) {
return 1;
} else if (val < 0) {
return -1;
} else {
return 0;
}
}
});
System.out.println("\n" + Arrays.toString(books));
// 按書名長度排序,長到短
Arrays.sort(books, new Comparator() {
@Override
public int compare(Object o1, Object o2) {
Book book1 = (Book) o1;
Book book2 = (Book) o2;
return book2.getName().length() - book1.getName().length();
}
});
System.out.println("\n" + Arrays.toString(books));
}
}
class Book {
private String name;
private double price;
public Book(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 "Book{" +
"name='" + name + '\'' +
"price=" + price +
'}' + "\n";
}
}