先序: 學習程式語言要先學個輪廓,剛開始只用學核心的部分,一些細節、不常用的內容先放著,現用現查即可;把常用的東西弄熟練了在慢慢補充。
1. Java 概述
Java 是一種物件導向的程式語言,由 Sun Microsystems(現在的 Oracle)在 1995 年推出。Java 程式可以在任何支援 Java 虛擬機器 (JVM) 的裝置上執行。Java 的核心理念是“一次編寫,到處執行”。
2. 基本語法
2.1 Java 程式結構
每個 Java 程式都由類 (class) 和方法 (method) 組成。以下是一個簡單的 Java 程式示例:
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello, World!");
}
}
public class HelloWorld
:定義一個名為HelloWorld
的公共類。public static void main(String[] args)
:主方法,是程式的入口點。System.out.println("Hello, World!");
:列印一行文字到控制檯。
2.2 註釋
Java 支援三種型別的註釋:
- 單行註釋:使用
//
- 多行註釋:使用
/* ... */
- 文件註釋:使用
/** ... */
3. 資料型別
Java 的資料型別分為兩大類:基本資料型別 (primitive types) 和引用資料型別 (reference types)。
3.1 基本資料型別
- 整型:
byte
,short
,int
,long
- 浮點型:
float
,double
- 字元型:
char
- 布林型:
boolean
int number = 10;
float pi = 3.14f;
char letter = 'A';
boolean isJavaFun = true;
3.2 引用資料型別
引用資料型別包括類 (class), 介面 (interface), 陣列 (array),以及列舉 (enum)。
4. 運算子
Java 提供了豐富的運算子,包括:
- 算術運算子:
+
,-
,*
,/
,%
- 賦值運算子:
=
,+=
,-=
,*=
,/=
,%=
- 比較運算子:
==
,!=
,>
,<
,>=
,<=
- 邏輯運算子:
&&
,||
,!
- 位運算子:
&
,|
,^
,~
,<<
,>>
,>>>
int a = 5;
int b = 10;
int sum = a + b; // 加法
boolean isEqual = (a == b); // 比較
5. 判斷和迴圈
5.1 條件語句
- if 語句:用於條件判斷
- switch 語句:用於多分支選擇
if (a > b) {
System.out.println("a is greater than b");
} else if (a < b) {
System.out.println("a is less than b");
} else {
System.out.println("a is equal to b");
}
switch (a) {
case 1:
System.out.println("a is 1");
break;
case 2:
System.out.println("a is 2");
break;
default:
System.out.println("a is not 1 or 2");
}
5.2 迴圈語句
- for 迴圈:用於固定次數的迴圈
- while 迴圈:用於條件控制的迴圈
- do-while 迴圈:至少執行一次的迴圈
for (int i = 0; i < 5; i++) {
System.out.println(i);
}
int j = 0;
while (j < 5) {
System.out.println(j);
j++;
}
int k = 0;
do {
System.out.println(k);
k++;
} while (k < 5);
5.3 常用遍歷方法
在 Java 中,遍歷陣列和字串是常見的操作。下面詳細介紹幾種常用的遍歷方法。
1. 遍歷陣列的方法
1.1 使用 for
迴圈
傳統的 for
迴圈是遍歷陣列的常見方法:
int[] numbers = {1, 2, 3, 4, 5};
for (int i = 0; i < numbers.length; i++) {
System.out.println(numbers[i]);
}
這裡的 i
是陣列的索引,透過 numbers[i]
獲取陣列元素。
1.2 使用增強型 for
迴圈(for-each
迴圈)
增強型 for
迴圈簡化了陣列的遍歷,不需要使用索引:
int[] numbers = {1, 2, 3, 4, 5};
for (int number : numbers) {
System.out.println(number);
}
這種方法直接獲取陣列中的每個元素,語法簡潔。
2. 遍歷字串的方法
2.1 使用 for
迴圈
字串可以看作是字元陣列,可以用 for
迴圈逐個字元地遍歷:
String text = "Hello";
for (int i = 0; i < text.length(); i++) {
System.out.println(text.charAt(i));
}
charAt(i)
方法返回字串中第 i
個字元。
2.2 使用增強型 for
迴圈(for-each
迴圈)
雖然增強型 for
迴圈不能直接用於 String
,但可以將字串轉換為字元陣列後進行遍歷:
String text = "Hello";
for (char ch : text.toCharArray()) {
System.out.println(ch);
}
toCharArray()
方法將字串轉換為字元陣列,然後進行遍歷。
2.3 使用 Stream API
同樣地,可以使用 Stream API
來遍歷字串:
String text = "Hello";
text.chars().forEach(c -> System.out.println((char) c));
chars()
方法返回一個包含字元的 IntStream
,需要將 int
型別轉換為 char
型別。
3. 其他的遍歷方法
3.1 使用迭代器(Iterator
)
對於集合類(如 List
、Set
等),可以使用 Iterator
進行遍歷:
List<String> list = Arrays.asList("A", "B", "C");
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
Iterator
提供了 hasNext()
和 next()
方法,用於順序訪問集合中的元素。
3.2 使用 forEach
方法
Java 8 引入的 forEach
方法可以直接用於遍歷集合和 Map
:
List<String> list = Arrays.asList("A", "B", "C");
list.forEach(System.out::println);
Map<Integer, String> map = new HashMap<>();
map.put(1, "One");
map.put(2, "Two");
map.forEach((key, value) -> System.out.println(key + " = " + value));
這種方法語法簡潔,尤其適合使用 Lambda 表示式進行處理。
6. 陣列
陣列是相同資料型別的集合,可以儲存固定大小的元素。
int[] numbers = new int[5];
numbers[0] = 1;
numbers[1] = 2;
// 其他元素初始化
int[] primes = {2, 3, 5, 7, 11};
System.out.println(primes[0]); // 輸出第一個元素
7. 物件導向程式設計
物件導向程式設計 (OOP) 是 Java 的核心概念,以下是幾個重要的物件導向概念:
7.1 介面
介面是一種抽象型別,定義了類必須實現的方法。介面中的所有方法預設都是抽象的(沒有方法體),且所有欄位預設都是 public static final
。
interface Animal {
void eat();
void sleep();
}
class Dog implements Animal {
@Override
public void eat() {
System.out.println("Dog eats");
}
@Override
public void sleep() {
System.out.println("Dog sleeps");
}
}
public class Main {
public static void main(String[] args) {
Dog dog = new Dog();
dog.eat();
dog.sleep();
}
}
7.2 抽象類
抽象類是不能被例項化的類,可以包含抽象方法和具體方法。抽象方法必須在子類中實現。
abstract class Animal {
abstract void makeSound();
public void sleep() {
System.out.println("Sleeping...");
}
}
class Dog extends Animal {
@Override
public void makeSound() {
System.out.println("Bark");
}
}
public class Main {
public static void main(String[] args) {
Dog dog = new Dog();
dog.makeSound();
dog.sleep();
}
}
7.3 繼承
繼承是指一個類(子類)繼承另一個類(父類)的屬性和方法。子類可以擴充套件或重寫父類的方法。
class Animal {
public void eat() {
System.out.println("Animal eats");
}
}
class Dog extends Animal {
@Override
public void eat() {
System.out.println("Dog eats");
}
}
public class Main {
public static void main(String[] args) {
Dog dog = new Dog();
dog.eat();
}
}
7.4 多型
多型允許同一個介面在不同的實現中表現出不同的行為。它是透過方法過載和方法重寫實現的。
class Animal {
public void makeSound() {
System.out.println("Some sound");
}
}
class Dog extends Animal {
@Override
public void makeSound() {
System.out.println("Bark");
}
}
class Cat extends Animal {
@Override
public void makeSound() {
System.out.println("Meow");
}
}
public class Main {
public static void main(String[] args) {
Animal myDog = new Dog();
Animal myCat = new Cat();
myDog.makeSound();
myCat.makeSound();
}
}
8. 輸入輸出 (I/O)
Java 的 I/O 庫提供了豐富的類和介面,用於檔案操作、資料流操作、網路通訊等。
Scanner 類
Scanner
類是 Java 5 引入的,用於從各種輸入源讀取資料,例如控制檯輸入、檔案、字串等。它提供了一系列方便的方法來解析基本型別和字串。
下面給的示例程式碼都是從控制檯獲取輸入
import java.util.Scanner;
public class ScannerExample {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.print("請輸入您的名字: ");
String name = scanner.nextLine(); // 讀取整行輸入
System.out.println("你好, " + name + "!");
System.out.print("請輸入您的年齡: ");
int age = scanner.nextInt(); // 讀取整數輸入
System.out.println("您 " + age + " 歲了!");
scanner.close(); // 關閉 Scanner
}
}
常用方法:
nextLine()
: 讀取一整行輸入,返回一個字串。nextLine().charAt(0)
: 讀取一行字串中的第一個,一般用這個讀取char型別變數。nextInt()
: 讀取一個整數。nextDouble()
: 讀取一個雙精度浮點數。nextBoolean()
: 讀取一個布林值。hasNext()
: 檢查是否有下一個輸入。hasNextLine()
: 檢查是否有下一行輸入。close()
: 關閉 Scanner。
BufferedReader 類
BufferedReader
類用於從字元輸入流中讀取文字,提供了緩衝功能以提高讀取效率。它通常與 InputStreamReader
一起使用,從標準輸入或檔案讀取資料。
使用 BufferedReader 從終端讀取資料
示例程式碼:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class BufferedReaderExample {
public static void main(String[] args) throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
System.out.print("請輸入您的名字: ");
String name = reader.readLine(); // 讀取整行輸入
System.out.println("你好, " + name + "!");
System.out.print("請輸入您的年齡: ");
int age = Integer.parseInt(reader.readLine()); // 讀取整行輸入並解析為整數
System.out.println("您 " + age + " 歲了!");
reader.close(); // 關閉 BufferedReader
}
}
常用方法:
readLine()
: 讀取一整行輸入,返回一個字串。close()
: 關閉 BufferedReader。
對比 Scanner 和 BufferedReader
相同點:
- 都可以用於從終端、檔案等源讀取輸入。
- 都提供了讀取整行輸入的方法:
nextLine()
和readLine()
。
不同點:
-
功能:
Scanner
提供了更多解析輸入資料的方法,如nextInt()
,nextDouble()
等,可以直接讀取基本型別資料。BufferedReader
主要用於讀取字串,需要手動解析基本型別資料。
-
效能:
BufferedReader
通常效能更高,因為它使用緩衝機制,適合讀取大量文字資料。Scanner
在方便性上有優勢,但效能可能稍遜色。
-
使用場景:
Scanner
更適合處理互動式的終端輸入,或者需要解析各種基本型別資料的場景。BufferedReader
更適合讀取大量文字資料,或者需要更高效的輸入操作的場景。
8.2 檔案操作
Java 提供了多種檔案操作類,如 FileReader
, FileWriter
, BufferedReader
, BufferedWriter
。
讀取檔案
使用 BufferedReader
從檔案中讀取資料。
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class FileRead {
public static void main(String[] args) {
try (BufferedReader br = new BufferedReader(new FileReader("test.txt"))) {
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
寫入檔案
使用 BufferedWriter
將資料寫入檔案。
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
public class FileWrite {
public static void main(String[] args) {
try (BufferedWriter bw = new BufferedWriter(new FileWriter("test.txt"))) {
bw.write("Hello, World!");
} catch (IOException e) {
e.printStackTrace();
}
}
}
8.3 輸出
將資料輸出到控制檯。
1. System.out.print()
- 示例:
輸出:// 輸出內容到控制檯,末尾沒有換行 System.out.print("Hello"); System.out.print("World");
HelloWorld
2. System.out.println()
- 示例:
// 輸出內容到控制檯,並在內容後自動新增換行符。 System.out.println("Hello"); System.out.println("World");
- 輸出:
Hello World
3. System.out.printf()
- 用法:
System.out.printf(formatString, arguments);
- 示例:
輸出:// 使用格式化字串輸出內容,類似於 C 語言中的 `printf`。允許你使用格式說明符控制輸出的格式。 int age = 25; double height = 1.75; System.out.printf("Age: %d years\n", age); System.out.printf("Height: %.2f meters\n", height);
Age: 25 years Height: 1.75 meters
常用格式說明符
- 整數:
%d
: 十進位制整數%x
: 十六進位制整數
- 浮點數:
%f
: 浮點數%.2f
: 浮點數,保留兩位小數
- 字串:
%s
: 字串
- 字元:
%c
: 單個字元
- 百分比:
%%
: 輸出百分號%
總結
System.out.print()
: 用於輸出內容,不換行。System.out.println()
: 用於輸出內容並換行。System.out.printf()
: 用於格式化輸出內容。
9、Java 集合框架
String常用方法
1. 建立與初始化
String()
:建立一個空字串。String(String original)
:建立一個新的字串,內容為指定的String
。
2. 字串操作
concat(String str)
:連線指定字串到當前字串末尾。substring(int beginIndex)
:從指定索引開始,返回子字串。substring(int beginIndex, int endIndex)
:返回從beginIndex
到endIndex
之間的子字串。
3. 查詢與比較
indexOf(String str)
:返回指定子字串第一次出現的索引。lastIndexOf(String str)
:返回指定子字串最後一次出現的索引。contains(CharSequence sequence)
:判斷當前字串是否包含指定字元序列。equals(Object anObject)
:比較兩個字串的內容是否相等。equalsIgnoreCase(String anotherString)
:忽略大小寫比較兩個字串的內容是否相等。compareTo(String anotherString)
:按字典順序比較兩個字串。
4. 替換與轉換
replace(char oldChar, char newChar)
:替換字串中的所有指定字元為新字元。replaceAll(String regex, String replacement)
:用正規表示式匹配並替換匹配的部分。toLowerCase()
:將字串轉換為小寫。toUpperCase()
:將字串轉換為大寫.trim()
:去除字串首尾的空白字元。
5. 分割與連線
split(String regex)
:根據正規表示式分割字串,返回字串陣列。join(CharSequence delimiter, CharSequence... elements)
:使用指定的分隔符連線多個字元序列。
6. 其他
charAt(int index)
:返回指定索引處的字元。java的String不可以透過str[0]
這樣的方式訪問length()
:返回字串的長度。isEmpty()
:判斷字串是否為空(長度為0)。toCharArray()
:將字串轉換為字元陣列。startsWith(String prefix)
:判斷字串是否以指定的字首開始。endsWith(String suffix)
:判斷字串是否以指定的字尾結束。matches(String regex)
:判斷字串是否匹配給定的正規表示式。
List 介面
List
是一個有序的集合,可以包含重複元素。常用實現類有 ArrayList
和 LinkedList
。
ArrayList
ArrayList
是一個基於動態陣列的資料結構,提供了快速的隨機訪問能力。它的主要特點是:
- 動態調整陣列大小:當元素超過陣列容量時,
ArrayList
會自動擴充套件。 - 訪問元素速度快:由於底層是陣列,透過索引訪問元素的時間複雜度為 O(1)。
- 插入和刪除操作相對較慢:插入或刪除元素時,可能需要移動陣列中的其他元素,時間複雜度為 O(n)。
常用方法:
add(E e)
: 新增元素到列表末尾。get(int index)
: 獲取指定索引位置的元素。set(int index, E element)
: 替換指定索引位置的元素。remove(int index)
: 移除指定索引位置的元素。size()
: 返回列表中元素的數量。
示例程式碼:
import java.util.ArrayList;
import java.util.List;
public class ArrayListExample {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("Apple");
list.add("Banana");
list.add("Cherry");
System.out.println("List: " + list);
System.out.println("Element at index 1: " + list.get(1));
list.set(1, "Blueberry");
System.out.println("Updated List: " + list);
list.remove(0);
System.out.println("List after removal: " + list);
}
}
LinkedList
LinkedList
是一個基於雙向連結串列的資料結構,提供了高效的插入和刪除操作。它的主要特點是:
- 連結串列節點:每個元素都是一個節點,包含元素值以及指向前一個和後一個節點的指標。
- 插入和刪除速度快:插入和刪除元素時只需調整指標,時間複雜度為 O(1)。
- 訪問元素速度慢:由於需要從頭開始遍歷連結串列,透過索引訪問元素的時間複雜度為 O(n)。
常用方法:
add(E e)
: 新增元素到列表末尾。get(int index)
: 獲取指定索引位置的元素。set(int index, E element)
: 替換指定索引位置的元素。remove(int index)
: 移除指定索引位置的元素。size()
: 返回列表中元素的數量。
示例程式碼:
import java.util.LinkedList;
import java.util.List;
public class LinkedListExample {
public static void main(String[] args) {
List<String> list = new LinkedList<>();
list.add("Apple");
list.add("Banana");
list.add("Cherry");
System.out.println("List: " + list);
System.out.println("Element at index 1: " + list.get(1));
list.set(1, "Blueberry");
System.out.println("Updated List: " + list);
list.remove(0);
System.out.println("List after removal: " + list);
}
}
Set 介面
Set
是一個不包含重複元素的集合。常用實現類有 HashSet
和 TreeSet
。
HashSet
HashSet
基於雜湊表實現,元素沒有順序。它的主要特點是:
- 無序集合:元素沒有特定的順序。
- 不允許重複元素:如果新增重複元素,
HashSet
會忽略它。 - 高效的插入、刪除和查詢操作:時間複雜度為 O(1)。
常用方法:
add(E e)
: 新增元素到集合中。remove(Object o)
: 從集合中移除指定元素。contains(Object o)
: 檢查集合是否包含指定元素。size()
: 返回集合中元素的數量。
示例程式碼:
import java.util.HashSet;
import java.util.Set;
public class HashSetExample {
public static void main(String[] args) {
Set<String> set = new HashSet<>();
set.add("Apple");
set.add("Banana");
set.add("Cherry");
set.add("Apple"); // 重複元素
System.out.println("Set: " + set);
System.out.println("Set contains 'Banana': " + set.contains("Banana"));
set.remove("Banana");
System.out.println("Set after removal: " + set);
}
}
TreeSet
TreeSet
基於紅黑樹實現,元素是有序的。它的主要特點是:
- 有序集合:元素按照自然順序或自定義順序排序。
- 不允許重複元素:如果新增重複元素,
TreeSet
會忽略它。 - 較高的插入、刪除和查詢操作效能:時間複雜度為 O(log n)。
常用方法:
add(E e)
: 新增元素到集合中。remove(Object o)
: 從集合中移除指定元素。contains(Object o)
: 檢查集合是否包含指定元素。size()
: 返回集合中元素的數量。
示例程式碼:
import java.util.Set;
import java.util.TreeSet;
public class TreeSetExample {
public static void main(String[] args) {
Set<String> set = new TreeSet<>();
set.add("Banana");
set.add("Apple");
set.add("Cherry");
System.out.println("Set: " + set);
System.out.println("Set contains 'Banana': " + set.contains("Banana"));
set.remove("Banana");
System.out.println("Set after removal: " + set);
}
}
Map 介面
Map
是一個鍵值對的集合,每個鍵最多隻能關聯一個值。常用實現類有 HashMap
和 TreeMap
。
HashMap
HashMap
基於雜湊表實現,鍵值對沒有順序。它的主要特點是:
- 無序集合:鍵值對沒有特定的順序。
- 不允許重複鍵:如果新增重複鍵,
HashMap
會覆蓋舊值。 - 高效的插入、刪除和查詢操作:時間複雜度為 O(1)。
常用方法:
put(K key, V value)
: 新增鍵值對到對映中。get(Object key)
: 獲取指定鍵的值。remove(Object key)
: 從對映中移除指定鍵值對。containsKey(Object key)
: 檢查對映是否包含指定鍵。size()
: 返回對映中鍵值對的數量。
示例程式碼:
import java.util.HashMap;
import java.util.Map;
public class HashMapExample {
public static void main(String[] args) {
Map<String, Integer> map = new HashMap<>();
map.put("Apple", 1);
map.put("Banana", 2);
map.put("Cherry", 3);
System.out.println("Map: " + map);
System.out.println("Value for 'Banana': " + map.get("Banana"));
map.remove("Banana");
System.out.println("Map after removal: " + map);
}
}
TreeMap
TreeMap
基於紅黑樹實現,鍵值對是有序的。它的主要特點是:
- 有序集合:鍵值對按照鍵的自然順序或自定義順序排序。
- 不允許重複鍵:如果新增重複鍵,
TreeMap
會覆蓋舊值。 - 較高的插入、刪除和查詢操作效能:時間複雜度為 O(log n)。
常用方法:
put(K key, V value)
: 新增鍵值對到對映中。get(Object key)
: 獲取指定鍵的值。remove(Object key)
: 從對映中移除指定鍵值對。containsKey(Object key)
: 檢查對映是否包含指定鍵。size()
: 返回對映中鍵值對的數量。
示例程式碼:
import java.util.Map;
import java.util.TreeMap;
public class TreeMapExample {
public static void main(String[] args) {
Map<String, Integer> map = new TreeMap<>();
map.put("Banana", 2);
map.put("Apple", 1);
map.put("Cherry", 3);
System.out.println("Map: " + map);
System.out.println("Value for 'Banana': " + map.get("Banana"));
map.remove("Banana");
System.out.println("Map after removal: " + map);
}
}
Queue 介面
Queue
是一個先進先出的集合,常用實現類有 LinkedList
和 PriorityQueue
。
LinkedList
LinkedList
實現了 Queue
介面,提供了基於連結串列的佇列實現。它的主要特點是:
- 雙向連結串列:可以作為佇列(FIFO)和雙端佇列(Deque)使用。
- 高效的插入和刪除操作:時間複雜度為 O(1)。
常用方法:
add(E e)
: 將指定元素插入此佇列的末尾。offer(E e)
: 將指定元素插入此佇列的末尾,如果成功則返回true
,如果佇列已滿則返回false
(一般不檢查佇列是否滿)。remove()
: 檢索並移除此佇列的頭部元素。poll()
: 檢索並移除此佇列的頭部元素,如果此佇列為空,則返回null
。element()
: 檢索但不移除此佇列的頭部元素。peek()
: 檢索但不移除此佇列的頭部元素,如果此佇列為空,則返回null
。
示例程式碼:
import java.util.LinkedList;
import java.util.Queue;
public class QueueExample {
public static void main(String[] args) {
Queue<String> queue = new LinkedList<>();
queue.add("Apple");
queue.offer("Banana");
queue.add("Cherry");
System.out.println("Queue: " + queue);
System.out.println("Head of the queue: " + queue.peek());
queue.remove();
System.out.println("Queue after removal: " + queue);
queue.poll();
System.out.println("Queue after poll: " + queue);
}
}
PriorityQueue
PriorityQueue
是一個基於優先順序堆(最小堆或最大堆)的佇列,元素按自然順序或自定義順序排序。它的主要特點是:
- 無界優先順序佇列:元素按照優先順序排序,不一定是先進先出(FIFO)。
- 預設最小堆:自然順序為最小堆,可自定義比較器實現最大堆。
- 高效的插入和刪除操作:時間複雜度為 O(log n)。
常用方法與 LinkedList
類似:
add(E e)
: 將指定元素插入此佇列。offer(E e)
: 將指定元素插入此佇列。remove()
: 檢索並移除此佇列的頭部元素。poll()
: 檢索並移除此佇列的頭部元素,如果此佇列為空,則返回null
。element()
: 檢索但不移除此佇列的頭部元素。peek()
: 檢索但不移除此佇列的頭部元素,如果此佇列為空,則返回null
。
示例程式碼:
import java.util.PriorityQueue;
import java.util.Queue;
public class PriorityQueueExample {
public static void main(String[] args) {
Queue<String> queue = new PriorityQueue<>();
queue.add("Banana");
queue.offer("Apple");
queue.add("Cherry");
System.out.println("PriorityQueue: " + queue);
System.out.println("Head of the queue: " + queue.peek());
queue.remove();
System.out.println("PriorityQueue after removal: " + queue);
queue.poll();
System.out.println("PriorityQueue after poll: " + queue);
}
}