- 上半部分內容是繼我的上一篇 JavaSE 基礎(十一) 字符串的姊妹篇 ,大家可以對照來看。
- 本篇內容(Project && 筆記)大家需要的話大家可以到我的Github Github 鏈接 上 Clone。
1.String 高級
1.1 - StringBuffer 概述
- 是一個線程安全的可變字符序列。
- String 是一個不可變的字符序列,而 StringBuffer 是一個可變的字符序列。
讀讀 API ??
A thread-safe, mutable sequence of characters. A string buffer is like a String, but can be modified. At any point in time it contains some particular sequence of characters, but the length and content of the sequence can be changed through certain method calls.
String buffers are safe for use by multiple threads. The methods are synchronized where necessary so that all the operations on any particular instance behave as if they occur in some serial order that is consistent with the order of the method calls made by each of the individual threads involved.
1.2 - StringBuffer 構造方法
public StringBuffer()
構造一個不帶字符的字符串緩沖區,初始容量為 16 個字節。
Constructs a string buffer with no characters in it and an initial capacity of 16 characters.
每個字符串緩沖區都有一定的容量。只要字符串緩沖區所包含的字符序列的長度沒有超出此容量,就無需分配新的內部緩沖區數組。如果內部緩沖區溢出,則此容量自動增大。從 JDK5 開始,為該類補充了一個單線程使用的等價類 StringBuilder
。與該類相比,通常應該優先使用 StringBuilder
,因為它支持所有相同的操作,但由于它不執行同步,所以速度更快。
As of release JDK 5, this class has been supplemented with an equivalent class designed for use by a single thread, StringBuilder. The StringBuilder class should generally be used in preference to this one, as it supports all of the same operations but it is faster, as it performs no synchronization.
StringBuffer(CharSequence suq)
構造一個字符串緩沖區,它包含與指定的charSequence
相同的字符。public StringBuffer(String str)
容量為字符長度 + 初始容量
1.3 - StringBuffer 基本方法
public int length()
容器中的字符個數,實際值public int capacity()
容器容量,理論值:字符串 length + 初始容量(16)
1.4 - StringBuffer 添加功能
-
public StringBuffer append(* *)
可以將任意類型數據添加到字符串緩沖區里面,并返回字符串緩沖區本身。
StringBuffer 是字符串緩沖區,當 new 的時候在堆內存創建了一個對象,底層是一個長度為 16 的字符數組,當調用添加方法時,不會再重新創建對象,而是在不斷的向原緩沖區添加字符。
-
public StringBuffer insert(* *)
可以在指定索引插入任意類型數據,到字符串緩沖區里面,并返回字符串緩沖區本身。
插入到 insert 這個索引位置,其他字符串向后移。
1.5 - StringBuffer 刪除功能
-
public StringBuffer deleteCharAt(int index)
根據索引刪除某個字符。
當緩沖區中這個索引上沒有元素時 ??
StringIndexOutOfBoundsException
-
public StringBuffer delete(int start, int end)
刪除 [start, end) 包含頭不包含尾。
清空緩沖區:sb.delete(0, sb.length())
1.6 - StingBuffer 替換、反轉功能
public StringBuffer replace(int start, int end, String str)
替換 [start, end) 包含頭不包含尾,String 的replace
方法可以轉換指定字符。public StringBuffer reverse()
將字符串反轉。
1.7 - StringBuffer 截取功能
-
public String substring(int start, int end)
截取 [start, end) 字符,通過返回值返回截取的字符串。
原字符串緩沖區不被改變
1.8 - StringBuffer 與 String 相互轉換
- String -> StringBuffer
- StringBuffer 構造方法:
public StringBuffer(String str)
- append 方法
- StringBuffer 構造方法:
- StringBuffer -> String
- 通過 String 構造方法,傳入 StringBuffer 參數。
- 通過 toString()
- 通過 substring()
1.9 - Test ????? 輸出數組
- 題目:輸出結果[1, 2, 3],用 StringBuffer 實現
- 數據:int[] arr = {1, 2, 3}
private static String arrayToString(int[] arr) {
StringBuffer sb = new StringBuffer();
for (int I = 0; I < arr.length; I++) {
if (I == 0) {
// “+” 是通過創建 StringBuffer 對象 append 后 toString() 實現的。
sb.insert(0, “[“ + arr[i] + “, “);
} else if (I == arr.length - 1) {
sb.append(arr[i]).append(‘]’);
} else {
sb.append(arr[i]).append(“, “);
}
}
return sb.toString();
}
好處:只有一個 StringBuffer 對象,不會產生過多內存垃圾。
1.10 - Test ????? 字符串反轉
- 題目:使用 StringBuffer,字符串反轉。
public class Test2 {
public static void test() {
Scanner sc = new Scanner(System.in);
System.out.print(“Please enter a line: “);
String line = sc.nextLine();
String reverseLine = reverseString(line);
System.out.println(reverseLine);
}
private static String reverseString(String str) {
StringBuffer sb = new StringBuffer(str); // String -> StringBuffer
sb.reverse(); // 將緩沖區中內容反轉
return sb.toString();
}
}
1.11 - StringBuffer 與 StringBuilder 區別
- StringBuffer 是 JDK1.0版本的,線程安全,效率低;StringBuilder 是 JDK1.5版本的,線程不安全,效率高。
- String 是一個不可變的字符序列。
1.12 - StringBuffer 與 StringBuilder 作為參數傳遞
- String 作為參數傳遞:String 雖然是引用數據類型,但是把它當做參數傳遞時,和基本數據類型是一樣的。
- StringBuffer 作為參數傳遞:引用數據類型傳遞。
2.數組高級
2.1 - 冒泡排序
- 原理:兩個相鄰位做比較,小數向前移,大數向后移。
- 每次比較最大的被數移動到最后一位。
// 外層循環控制趟數,不參與運算,共比較 length - 1 趟。
for (int I = 0; I < arr.length - 1; I++) {
for (int j = 0; j < arr.length - 1 - I; j++) {
if (arr[j] > arr[j + 1]) {
arr[j] = arr[j] ^ arr[j + 1];
arr[j + 1] = arr[j] ^ arr[j + 1];
arr[j] = arr[j] ^ arr[j + 1];
}
}
}
2.2 - 選擇排序
- 用一個索引位置上的元素,依次與其他索引位置上的元素比較。
for (int I = 0; I < arr.length - 1; I++) {
for (int j = I + 1; j < arr.length; j++) {
if (arr[I] > arr[j]) {
arr[i] = arr[i] ^ arr[j];
arr[j] = arr[i] ^ arr[j];
arr[i] = arr[i] ^ arr[j];
}
}
}
2.3 - 二分查找
- 使用前提:數組是有序的。
public static int search_binary(int[] arr, int target) {
int min = 0;
int max = arr.length - 1;
int mid;
while (true) {
if (min > max) {
return -1;
}
mid = (min + max) / 2;
if (arr[mid] > target) {
max = mid - 1;
}
if (arr[mid] < target) {
min = mid + 1;
}
if (arr[mid] == target) {
return mid;
}
}
}
2.4 - Arrays 概述
-
public static String toString(int[] a)
數組 -> 字符串
讀讀原碼 ??
public static String toString(int[] a) {
if (a == null)
// 如果傳入數組是 null 返回 “null”
return “null”;
// 最大索引
int iMax = a.length - 1;
// 如果數組中沒有元素,返回[]
if (iMax == -1)
return “[]”;
// 線程不安全,效率高
StringBuilder b = new StringBuilder();
// 將 ‘[‘ 添加到字符串緩沖區
b.append(‘[‘);
for (int I = 0; ; I++) {
// 將元素拼接到到字符串緩沖區
b.append(a[I]);
// 當輸出為最后一個元素時,將 ‘]’ 拼接到字符串緩沖區
if (I == iMax)
return b.append(‘]’).toString();
// 在元素后,拼接 ‘]’ 到字符串緩沖區
b.append(“, “);
}
}
public static void sort(int[] a)
排序-
private static int binarySearch(int[] a, int fromIndex, int toIndex, int key)
二分查找- 數組需要是有序的。
- 如果找不到則返回- (插入點 ) - 1。
- 如果數組中有多個要查找的值,不保證返回哪一個。
- 返回值 < 0 說明沒有找到。
讀讀原碼 ??
private static int binarySearch0(int[] a, int fromIndex, int toIndex, int key) {
// 最小索引 0
int low = fromIndex;
// 最大索引 length - 1
int high = toIndex - 1;
// 最小索引 <= 最大索引 作為循環判斷
while (low <= high) {
// >>> 求出中間索引值
int mid = (low + high) >>> 1;
// 通過中間索引獲取中間值
int midVal = a[mid];
// 查找值在中間值右側
if (midVal < key)
// 最小索引變化
low = mid + 1;
// 查找值在中間值左側
else if (midVal > key)
high = mid - 1;
else
// 中間值 == 查找值
return mid; // key found
}
// 如果跳出循環,說明符合 low <= high 條件,沒有找到返回 -(low + 1)
return -(low + 1); // key not found.
}
3.Integer 基本數據類型包裝類
3.1 - Integer 概述
- 將基本數據類型封裝成對象的好處在于,可以在對象中定義更多的功能方法操作數據
- 常用操作之一:用于基本數據類型與字符串之間的轉換。
byte -> Byte
short -> Short
int -> Integer
long -> Long
float -> Float
double -> Double
char -> Character
boolean -> Boolean
3.2 - 進制轉換
public static String toBinaryString(int i)
轉二進制。public static String toHexString(int i)
轉十六進制。public static String toOctalString(int i)
轉八進制。
3.3 - 常量及構造方法
public static final int MAX_VALUE
最大 int 數。public static final int MIN_VALUE
最小 int 數public Integer(int value)
int 構造。public Integer(String s) throws NumberFormatException
String 構造
Integer i = new Integer("abc");
NumberFormatException:數字格式異常
3.4 - int 與 String 互相轉換
- int -> String
int i1 = 100;
Integer i2 = new Integer(i1);
// 第一種
String s1 = i1 + "";
// 第二種
String s2 = String.valueOf(i1);
// 第三種
String s3 = i2.toString();
// 第四種
String s4 = Integer.toString(i1);
- String -> int
基本數據類型包裝類有 8 種,其中 7 種都有parseX
方法,可以用來將字符串轉換為基本數據類型。char 的包裝類中沒有parseX
,通過 String 的toCharArray()
將字符串轉換為字符數組。
String s = "200";
// 第一種
int i1 = new Integer(s).intValue;
// 第二種
int i2 = Integer.parseInt(s);
3.5 - 拆裝箱
JDK1.5新特性
自動裝箱:把基本數據類型 -> 包裝數據類型
Integer i = 100;
自動拆箱:包裝數據類型 -> 把基本數據類型
int a = i;
注意事項:
Integer i = null;
,底層用 i 調用intValue()
NullPointerException
3.6 - 面試題
- 自動裝箱創建 Integer 重新創建對象問題。
{
Integer i1 = 97;
Integer i2 = 97;
System.out.println(i1 == i2); // true
System.out.println(i1.equals(i2)); // true
}
{
Integer i1 = 128;
Integer i2 = 128;
System.out.println(i1 == i2); // false
System.out.println(i1.equals(i2)); // true
}
通過自動裝箱創建 Integer,如果沒有超過 byte 取值范圍,就不會自動創建對象。而是從常量池中取,如果超過了 byte 取值范圍,則會重新創建對象。
悄悄話 ??
- 今天第一次上傳了 project 和 PDF 筆記,不知道對大家學習有沒有幫助,大家可以在簡書給我或者我的 Github 倉庫下給我留言,有好的建議的話,在下次專題文章中我都會采納的??。
- 現在每天的學習任務越來越重了,因為昨天放假一天,自己預習的時候整理好的筆記,今天上課和自習的時候又排了一下版面,還剩不多時間預習明天內容了,先不說了小伙伴們,我要去準備預習下明天內容了,大家晚安。
彩蛋 ??
-
最近開通了簡書專題 JavaSE 成長之路,主要為一樣正在 JavaSE 修行中的簡友們提供了技術交流的平臺,希望大家多多投稿交流互動。
-
??Project
-
??Note