先序: 學習編程語言要先學個輪廓,剛開始只用學核心的部分,一些細節、不常用的內容先放著,現用現查即可;把常用的東西弄熟練了在慢慢補充。 1. Java 概述 Java 是一種面向對象的編程語言,由 Sun Microsystems(現在的 Oracle)在 1995 年推出。Java 程式可以在任何 ...
先序: 學習編程語言要先學個輪廓,剛開始只用學核心的部分,一些細節、不常用的內容先放著,現用現查即可;把常用的東西弄熟練了在慢慢補充。
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);
}
}