Java 學習記錄45 — LinkedList

張小雄
5 min readMar 13, 2021

--

今天學習 LinkedList

import java.util.Iterator;
import java.util.LinkedList;
public class LinkedListTest {
public static void main(String[] args) {
LinkedList<String> placeToVisit = new LinkedList<String>();
placeToVisit.add("Taipei");
placeToVisit.add("New Taipei");
placeToVisit.add("Taoyuan");
placeToVisit.add("Taichung");
placeToVisit.add("Tainan");
placeToVisit.add("Kaohsiung");
printList(placeToVisit); placeToVisit.add(1, "Middle Taipei");
printList(placeToVisit);
placeToVisit.remove(4);
printList(placeToVisit);
} private static void printList(LinkedList<String> linkedList) {
Iterator<String> i = linkedList.iterator();
while (i.hasNext()) {
System.out.println("Now visiting City of " + i.next());
}
System.out.println("=============================");
}
}

輸出結果:

Now visiting City of Taipei

Now visiting City of New Taipei

Now visiting City of Taoyuan

Now visiting City of Taichung

Now visiting City of Tainan

Now visiting City of Kaohsiung

=============================

Now visiting City of Taipei

Now visiting City of Middle Taipei

Now visiting City of New Taipei

Now visiting City of Taoyuan

Now visiting City of Taichung

Now visiting City of Tainan

Now visiting City of Kaohsiung

=============================

Now visiting City of Taipei

Now visiting City of Middle Taipei

Now visiting City of New Taipei

Now visiting City of Taoyuan

Now visiting City of Tainan

Now visiting City of Kaohsiung

=============================

printList()

用新方法來循環,跟用 for 是一樣的

private static void printList(LinkedList<String> linkedList) {
for (String s : linkedList) {
System.out.println("Now visiting City of " + s);
}
System.out.println("=============================");
}
import java.util.Iterator;
import java.util.LinkedList;
import java.util.ListIterator;
public class LinkedListTest {
public static void main(String[] args) {
LinkedList<String> placeToVisit = new LinkedList<String>();
addInOrder(placeToVisit,"Taipei");
addInOrder(placeToVisit,"New Taipei");
addInOrder(placeToVisit,"Taoyuan");
addInOrder(placeToVisit,"Taichung");
addInOrder(placeToVisit,"Tainan");
addInOrder(placeToVisit,"Kaohsiung");
printList(placeToVisit); addInOrder(placeToVisit,"Taipei");
// placeToVisit.add(1, "Taipei");
// printList(placeToVisit);
//
// placeToVisit.remove(4);
// printList(placeToVisit);
} private static void printList(LinkedList<String> linkedList) {
Iterator<String> i = linkedList.iterator();
while (i.hasNext()) {
System.out.println("Now visiting City of " + i.next());
}
System.out.println("=============================");
}
private static boolean addInOrder(LinkedList<String> linkedList, String newCity) {
ListIterator<String> stringListIterator = linkedList.listIterator();
while (stringListIterator.hasNext()) {
int comparison = stringListIterator.next().compareTo(newCity);
if (comparison == 0) {
// equal, no add
System.out.println(newCity + " is already included as a destination");
return false;
} else if (comparison > 0) {
// new City should appear before this one
// Bcity -> Acity
stringListIterator.previous();
stringListIterator.add(newCity);
return true;
} else if (comparison < 0) {
// move on
}
}
stringListIterator.add(newCity);
return true;
}
}

把加入的程式做字母順序排列

輸出結果:

Now visiting City of Kaohsiung

Now visiting City of New Taipei

Now visiting City of Taichung

Now visiting City of Tainan

Now visiting City of Taipei

Now visiting City of Taoyuan

=============================

Taipei is already included as a destination

邏輯解釋:

while (linkedlist has next element is true) {
int comparison = linkedlist go to next element,
and next element compare to parameter newCity;

compare Alphabet order(A to Z, A is smallest, Z is biggest)

if next element is Axxxx, new city is Bxxxx
comparison will be negative, because A < B

if next element is Bxxxx, new city is Axxxx
comparison will be positive, because B > A

if next element is Axxxx, new city is Axxxx
comparison will be 0, because A = B

新增功能

import java.util.LinkedList;
import java.util.ListIterator;
import java.util.Scanner;
public class LinkedListTest {
public static void main(String[] args) {
LinkedList<String> placeToVisit = new LinkedList<String>();
addInOrder(placeToVisit, "Taipei");
addInOrder(placeToVisit, "New Taipei");
addInOrder(placeToVisit, "Taoyuan");
addInOrder(placeToVisit, "Taichung");
addInOrder(placeToVisit, "Tainan");
addInOrder(placeToVisit, "Kaohsiung");
printList(placeToVisit);
visit(placeToVisit); } private static void printList(LinkedList<String> linkedList) {
for (String s : linkedList) {
System.out.println("Now visiting City of " + s);
}
System.out.println("=============================");
}
private static void addInOrder(LinkedList<String> linkedList, String newCity) {
ListIterator<String> stringListIterator = linkedList.listIterator();
while (stringListIterator.hasNext()) {
int comparison = stringListIterator.next().compareTo(newCity);
if (comparison == 0) {
// equal, no add
System.out.println(newCity + " is already included as a destination");
return;
} else if (comparison > 0) {
// new City should appear before this one
// B city -> A city
stringListIterator.previous();
stringListIterator.add(newCity);
return;
}
}
stringListIterator.add(newCity);
}
private static void visit(LinkedList<String> cities) {
Scanner scanner = new Scanner(System.in);
boolean quit = false;
boolean goingForward = true;
ListIterator<String> listIterator = cities.listIterator();
if (cities.isEmpty()) {
System.out.println("No cities in the itinerary");
return;
} else {
System.out.println("Now visiting " + listIterator.next());
printMenu();
}
while (!quit) {
int action = scanner.nextInt();
scanner.nextLine();
switch (action) {
case 0:
System.out.println("Vacation over!");
quit = true;
break;
case 1:
if (listIterator.hasNext()) {
System.out.println("Now visiting " + listIterator.next());
} else {
System.out.println("Reached the end of the list");
}
break;
case 2:
if (listIterator.hasPrevious()) {
System.out.println("Now visiting " + listIterator.previous());
} else {
System.out.println("We are at the start of the list");
}
break;
case 3:
printMenu();
break;
}
}
} private static void printMenu() {
System.out.println("Available actions:\npress ");
System.out.println("0 - to quit\n" +
"1 - go to next city\n" +
"2 - go to previous city\n" +
"3 - print menu options");
}
}

輸出結果:

Now visiting City of Kaohsiung

Now visiting City of New Taipei

Now visiting City of Taichung

Now visiting City of Tainan

Now visiting City of Taipei

Now visiting City of Taoyuan

=============================

Now visiting Kaohsiung

Available actions:

press

0 — to quit

1 — go to next city

2 — go to previous city

3 — print menu options

1(此行為用戶輸入)

Now visiting New Taipei

2(此行為用戶輸入)

Now visiting New Taipei

2(此行為用戶輸入)

Now visiting Kaohsiung

把城市存入 LinkedList 後

寫了一個 Method visit

可以讓訪問的城市 選擇往前往後走

但出了一個小 Bug

往前走的時候 會重複一次舊的

沒有馬上往前走

第一次輸入 2 往前走的時候

還是顯示 New Taipei

等到第二次輸入 2 才真的往前走

所以要修正

Tim 的解釋是說 是因為 LinkedList 指針沒有停留在當前元素 而是停在兩個元素之間

不過他的解釋我是看不太懂 還牽扯到了 tortoise and hare algorithm 叫我們可以自己 Google

P.S 我順便把 Tim 前面沒用到的地方照著 Intellij 的指示修正了 所以跟前面有些許不同

改 bug

import java.util.LinkedList;
import java.util.ListIterator;
import java.util.Scanner;
public class LinkedListTest {
public static void main(String[] args) {
LinkedList<String> placeToVisit = new LinkedList<String>();
addInOrder(placeToVisit, "Taipei");
addInOrder(placeToVisit, "New Taipei");
addInOrder(placeToVisit, "Taoyuan");
addInOrder(placeToVisit, "Taichung");
addInOrder(placeToVisit, "Tainan");
addInOrder(placeToVisit, "Kaohsiung");
printList(placeToVisit);
visit(placeToVisit); } private static void printList(LinkedList<String> linkedList) {
for (String s : linkedList) {
System.out.println("Now visiting City of " + s);
}
System.out.println("=============================");
}
private static void addInOrder(LinkedList<String> linkedList, String newCity) {
ListIterator<String> stringListIterator = linkedList.listIterator();
while (stringListIterator.hasNext()) {
int comparison = stringListIterator.next().compareTo(newCity);
if (comparison == 0) {
// equal, no add
System.out.println(newCity + " is already included as a destination");
return;
} else if (comparison > 0) {
// new City should appear before this one
// B city -> A city
stringListIterator.previous();
stringListIterator.add(newCity);
return;
}
}
stringListIterator.add(newCity);
}
private static void visit(LinkedList<String> cities) {
Scanner scanner = new Scanner(System.in);
boolean quit = false;
boolean goingForward = true;
ListIterator<String> listIterator = cities.listIterator();
if (cities.isEmpty()) {
System.out.println("No cities in the itinerary");
return;
} else {
System.out.println("Now visiting " + listIterator.next());
printMenu();
}
while (!quit) {
int action = scanner.nextInt();
scanner.nextLine();
switch (action) {
case 0:
System.out.println("Vacation over!");
quit = true;
break;
case 1:
if (!goingForward) {
if (listIterator.hasNext()) {
listIterator.next();
}
goingForward = true;
}
if (listIterator.hasNext()) {
System.out.println("Now visiting " + listIterator.next());
} else {
System.out.println("Reached the end of the list");
goingForward = false;
}
break;
case 2:
if (goingForward) {
if (listIterator.hasPrevious()) {
listIterator.previous();
}
goingForward = false;
}
if (listIterator.hasPrevious()) {
System.out.println("Now visiting " + listIterator.previous());
} else {
System.out.println("We are at the start of the list");
goingForward = true;
}
break;
case 3:
printMenu();
break;
}
}
} private static void printMenu() {
System.out.println("Available actions:\npress ");
System.out.println("0 - to quit\n" +
"1 - go to next city\n" +
"2 - go to previous city\n" +
"3 - print menu options");
}
}

簡單的說 goingFoward 的用意就是檢測方向的改變

因為原來的代碼,當改變方向時,會重複顯示當前元素

所以寫成用 goingFoward 來判斷是否改變方向

當有改變方向,就連續往後或往前兩次,就可以規避此情況

連跳兩次,只顯示第二次的元素,這樣就不會出現重複了

--

--

張小雄
張小雄

Written by 張小雄

記錄成為軟體工程師的過程

No responses yet