一、繼承、介面與多型
繼承(Inheritance)的語法
l 語法:
class 子類別名稱 extends 父類別名稱{
敘述區段
}
class 子類別名稱 extends 父類別名稱{
敘述區段
}
l 一個子類別(Subclass)只能繼承一個父類別(Superclass),子類別除擁有父類別的功能,還具有父類別所沒有的功能。
l 子類別不能繼承父類別用private修飾子所宣告的成員。
l 子類別可以繼承父類別用protected修飾子宣告的成員,而該成員可在同一套件內的類別所建立之物件使用。
l 子類別可以繼承父類別用public修飾子宣告的成員,而該成員可在同一套件或不同套件內的類別所建立之物件使用。
繼承與方法覆寫(Override)
l 如果子類別和父類別有相同的方法時,若使用子類別產生物件,當使用到這個方法時,子類別的方法會覆蓋父類別同名稱的方法;但如果傳入引數的資料型別不同、個數不同或順序不同,就會變成方法多載。
l 範例:
package testPackage;
class test2{
public void getMax(int a, int b){
int c;
if (a > b){
c = a;}
else{
c = b;}
System.out.println(a + " and " + b + ", Get Max: " + c);
}
public void add(int a, int b){
System.out.println(a + " + " + b + " = " + (a + b));
}
}
class sonTest2 extends test2{
public void getMax(int a, int b){
if (a > b){
System.out.println(a + " and " + b + ", Get Max: " + a);}
else if (a < b){
System.out.println(a + " and " + b + ", Get Max: " + b);}
else{
System.out.println(a + " and " + b + " Are the Same");}
}
public void minus(int a, int b){
System.out.println(a + " - " + b + " = " + (a - b));
}
}
public class test{
public static void main(String[] args){
test2 obj = new test2();
// 使用父類別自己的方法
obj.getMax(20, 20);
sonTest2 sonObj = new sonTest2();
// 使用子類別覆寫自父類別的方法
sonObj.getMax(20, 20);
// 使用子類別繼承自父類別的方法
sonObj.add(10, 20);
// 使用子類別自己的方法
sonObj.minus(20, 30);
}
}
package testPackage;
class test2{
public void getMax(int a, int b){
int c;
if (a > b){
c = a;}
else{
c = b;}
System.out.println(a + " and " + b + ", Get Max: " + c);
}
public void add(int a, int b){
System.out.println(a + " + " + b + " = " + (a + b));
}
}
class sonTest2 extends test2{
public void getMax(int a, int b){
if (a > b){
System.out.println(a + " and " + b + ", Get Max: " + a);}
else if (a < b){
System.out.println(a + " and " + b + ", Get Max: " + b);}
else{
System.out.println(a + " and " + b + " Are the Same");}
}
public void minus(int a, int b){
System.out.println(a + " - " + b + " = " + (a - b));
}
}
public class test{
public static void main(String[] args){
test2 obj = new test2();
// 使用父類別自己的方法
obj.getMax(20, 20);
sonTest2 sonObj = new sonTest2();
// 使用子類別覆寫自父類別的方法
sonObj.getMax(20, 20);
// 使用子類別繼承自父類別的方法
sonObj.add(10, 20);
// 使用子類別自己的方法
sonObj.minus(20, 30);
}
}
繼承與建構式
l 若使用子類別產生物件,子類別的父類別及其以上層級的預設建構式都會執行,由最上層類別預設建構式先執行,依序往下層執行至該層的預設建構式。
l 範例:
package testPackage;
class test2{
test2(){
System.out.println("Execute test2 Constructor");
}
}
class sonTest2 extends test2{
sonTest2(){
System.out.println("Execute sonTest2 Constructor");
}
}
class grandsonTest2 extends sonTest2{
grandsonTest2(){
System.out.println("Execute grandsonTest2 Constructor");
}
}
public class test{
public static void main(String[] args){
// 採匿名物件的方式來建立物件實體
new grandsonTest2();
}
}
package testPackage;
class test2{
test2(){
System.out.println("Execute test2 Constructor");
}
}
class sonTest2 extends test2{
sonTest2(){
System.out.println("Execute sonTest2 Constructor");
}
}
class grandsonTest2 extends sonTest2{
grandsonTest2(){
System.out.println("Execute grandsonTest2 Constructor");
}
}
public class test{
public static void main(String[] args){
// 採匿名物件的方式來建立物件實體
new grandsonTest2();
}
}
繼承與使用super呼叫父類別
l 範例:
package testPackage;
class test2{
private int height;
public int weight;
test2(int height, int weight){
this.height = height;
this.weight = weight;
}
public void showData(){
System.out.println("Height: " + this.height);
}
}
class sonTest2 extends test2{
private int age;
sonTest2(int height, int weight, int age){
// 使用super呼叫父類別test2(int height, int weight)建構式
super(height, weight);
this.age = age;
}
public void showData(){
// 使用super呼叫父類別showData()方法成員
super.showData();
// 使用super呼叫父類別weight資料成員
System.out.println("Weight: " + super.weight);
System.out.println("Age: " + this.age);
}
}
public class test{
public static void main(String[] args){
sonTest2 obj = new sonTest2(65, 171, 26);
obj.showData();
}
}
package testPackage;
class test2{
private int height;
public int weight;
test2(int height, int weight){
this.height = height;
this.weight = weight;
}
public void showData(){
System.out.println("Height: " + this.height);
}
}
class sonTest2 extends test2{
private int age;
sonTest2(int height, int weight, int age){
// 使用super呼叫父類別test2(int height, int weight)建構式
super(height, weight);
this.age = age;
}
public void showData(){
// 使用super呼叫父類別showData()方法成員
super.showData();
// 使用super呼叫父類別weight資料成員
System.out.println("Weight: " + super.weight);
System.out.println("Age: " + this.age);
}
}
public class test{
public static void main(String[] args){
sonTest2 obj = new sonTest2(65, 171, 26);
obj.showData();
}
}
繼承與使用final禁止被覆寫
l 如果在類別加上final,表示無法被子類別繼承。
如果在資料成員加上final,表示無法被變更且一定要有常數初值。
如果在方法成員加上final,表示無法被子類別覆寫;但如果傳入引數的資料型別不同、個數不同或順序不同,就會變成方法多載。
如果在資料成員加上final,表示無法被變更且一定要有常數初值。
如果在方法成員加上final,表示無法被子類別覆寫;但如果傳入引數的資料型別不同、個數不同或順序不同,就會變成方法多載。
l 範例:
package testPackage;
// 在類別加上final
final class test2{
int hpBaseStat;
}
class test3{
// 在資料成員加上final
private final int speedBaseStat = 110;
// 在方法成員加上final
public final void showData(String pokemon){
System.out.println(pokemon + "'s Speed Base Stat: " + speedBaseStat);
}
}
public class test{
public static void main(String[] args){
test3 obj = new test3();
obj.showData("Gengar");
}
}
package testPackage;
// 在類別加上final
final class test2{
int hpBaseStat;
}
class test3{
// 在資料成員加上final
private final int speedBaseStat = 110;
// 在方法成員加上final
public final void showData(String pokemon){
System.out.println(pokemon + "'s Speed Base Stat: " + speedBaseStat);
}
}
public class test{
public static void main(String[] args){
test3 obj = new test3();
obj.showData("Gengar");
}
}
繼承與使用static禁止被覆寫
l 如果在方法成員加上static,表示無法被子類別覆寫;但如果傳入引數的資料型別不同、個數不同或順序不同,就會變成方法多載。
l 範例:
package testPackage;
class test2{
public static int a = 10, b = 20;
public static void add(){
System.out.println(a + " + " + b + " = " + (a + b));
}
}
public class test{
public static void main(String[] args){
test2.add();
}
}
package testPackage;
class test2{
public static int a = 10, b = 20;
public static void add(){
System.out.println(a + " + " + b + " = " + (a + b));
}
}
public class test{
public static void main(String[] args){
test2.add();
}
}
抽象類別與抽象方法
l 語法:
abstract class 類別名稱{
修飾子 abstract 傳回值型別 抽象方法名稱(引數串列);
}
abstract class 類別名稱{
修飾子 abstract 傳回值型別 抽象方法名稱(引數串列);
}
l 抽象類別:
抽象類別是範本作用的父類別,不能使用new產生物件實體,只能被繼承,繼承它的子類別必須依照它的格式來定義。
抽象類別是範本作用的父類別,不能使用new產生物件實體,只能被繼承,繼承它的子類別必須依照它的格式來定義。
l 一般方法與抽象方法:
抽象類別內的方法成員,可以是一般方法成員或抽象方法成員;一般方法成員內有敘述區段,而抽象方法成員只有一行宣告敘述。
抽象類別內的方法成員,可以是一般方法成員或抽象方法成員;一般方法成員內有敘述區段,而抽象方法成員只有一行宣告敘述。
l 抽象方法:
抽象方法必須使用abstract關鍵字宣告,因必須被子類別繼承,修飾子不能為private。
抽象方法必須使用abstract關鍵字宣告,因必須被子類別繼承,修飾子不能為private。
l 抽象類別與抽象方法的繼承:
抽象類別被子類別繼承後,其抽象方法必須被子類別覆寫;此外因抽象類別無法建立物件實體,其建構式、資料成員與一般方法成員若要由子類別呼叫,必須使用super敘述。
抽象類別被子類別繼承後,其抽象方法必須被子類別覆寫;此外因抽象類別無法建立物件實體,其建構式、資料成員與一般方法成員若要由子類別呼叫,必須使用super敘述。
l 範例:
package testPackage;
abstract class testAbstract{
// 資料成員
int stat = 100;
// 一般方法成員
public static void showData(){
System.out.println("4 Effort Points Convert to 1 Stat Point");
}
// 抽象方法成員
public abstract void addStat(int effort);
}
class testPoke extends testAbstract{
public void addStat(int effort){
System.out.println("Before Receiving Effort Points, Stat: " + stat);
stat += (effort / 4);
System.out.println("After Receiving Effort Points, Stat: " + stat);
}
}
public class test{
public static void main(String[] args){
testAbstract.showData();
testPoke sylveon = new testPoke();
sylveon.addStat(252);
}
}
package testPackage;
abstract class testAbstract{
// 資料成員
int stat = 100;
// 一般方法成員
public static void showData(){
System.out.println("4 Effort Points Convert to 1 Stat Point");
}
// 抽象方法成員
public abstract void addStat(int effort);
}
class testPoke extends testAbstract{
public void addStat(int effort){
System.out.println("Before Receiving Effort Points, Stat: " + stat);
stat += (effort / 4);
System.out.println("After Receiving Effort Points, Stat: " + stat);
}
}
public class test{
public static void main(String[] args){
testAbstract.showData();
testPoke sylveon = new testPoke();
sylveon.addStat(252);
}
}
介面(Interface)
l 語法:
interface 介面名稱{
成員存取修飾子 資料型別 資料成員名稱 = 初值;
成員存取修飾子 傳回傳型別 方法成員名稱(引數串列);
}
interface 介面名稱{
成員存取修飾子 資料型別 資料成員名稱 = 初值;
成員存取修飾子 傳回傳型別 方法成員名稱(引數串列);
}
l 介面的資料成員:
介面內所定義的變數在編譯時會變成public及final型態,因此介面的變數為常數型態。
介面內所定義的變數在編譯時會變成public及final型態,因此介面的變數為常數型態。
l 介面的方法成員:
介面內所定義的任何方法都不可以被完整地描述,只提供方法的定義而不實作,在編譯時會變成public及abstract型態。
介面內所定義的任何方法都不可以被完整地描述,只提供方法的定義而不實作,在編譯時會變成public及abstract型態。
l 介面用以達成多重繼承:
一個類別可以有多個介面的特質,而不管類別是什麼關係,如父類別、子類別等,也可以使用implements實作同一個介面。
一個類別可以有多個介面的特質,而不管類別是什麼關係,如父類別、子類別等,也可以使用implements實作同一個介面。
l 介面實作範例:
package testPackage;
interface testInterface{
// 資料成員
public int totalEffort = 255;
// 方法成員
public void addStat(int effort);
}
class testPoke implements testInterface{
int stat = 100;
public void addStat(int effort){
System.out.println("Before Receiving Effort Points, Stat: " + stat);
stat += (effort / 4);
System.out.println("After Receiving Effort Points, Stat: " + stat);
}
}
public class test{
public static void main(String[] args){
System.out.println("Total Effort Points: " + testInterface.totalEffort);
testPoke sylveon = new testPoke();
sylveon.addStat(252);
}
}
package testPackage;
interface testInterface{
// 資料成員
public int totalEffort = 255;
// 方法成員
public void addStat(int effort);
}
class testPoke implements testInterface{
int stat = 100;
public void addStat(int effort){
System.out.println("Before Receiving Effort Points, Stat: " + stat);
stat += (effort / 4);
System.out.println("After Receiving Effort Points, Stat: " + stat);
}
}
public class test{
public static void main(String[] args){
System.out.println("Total Effort Points: " + testInterface.totalEffort);
testPoke sylveon = new testPoke();
sylveon.addStat(252);
}
}
l 介面繼承範例:
package testPackage;
interface tmMove{
public void moveOne();
public void moveTwo();
}
interface learnset extends tmMove{
public void moveThree();
public void moveFour();
}
// 一定要將所有介面方法成員的敘述區段完成
class testPoke implements learnset{
public void moveOne(){
System.out.println("Gengar's Move: Thunderbolt");
}
public void moveTwo(){
System.out.println("Gengar's Move: Sludge Bomb");
}
public void moveThree(){
System.out.println("Gengar's Move: Shadow Ball");
}
public void moveFour(){
System.out.println("Gengar's Move: Destiny Bond");
}
}
public class test{
public static void main(String[] args){
testPoke gengar = new testPoke();
gengar.moveOne();
gengar.moveTwo();
gengar.moveThree();
gengar.moveFour();
}
}
package testPackage;
interface tmMove{
public void moveOne();
public void moveTwo();
}
interface learnset extends tmMove{
public void moveThree();
public void moveFour();
}
// 一定要將所有介面方法成員的敘述區段完成
class testPoke implements learnset{
public void moveOne(){
System.out.println("Gengar's Move: Thunderbolt");
}
public void moveTwo(){
System.out.println("Gengar's Move: Sludge Bomb");
}
public void moveThree(){
System.out.println("Gengar's Move: Shadow Ball");
}
public void moveFour(){
System.out.println("Gengar's Move: Destiny Bond");
}
}
public class test{
public static void main(String[] args){
testPoke gengar = new testPoke();
gengar.moveOne();
gengar.moveTwo();
gengar.moveThree();
gengar.moveFour();
}
}
多型(Polymorphism)
l 不同物件執行相同名稱的方法,卻可以得到不同的結果:
使用父類別變數參考到子類別物件後,即透過父類別變數來存取子類別與父類別同時擁有的資料成員、方法成員。
使用父類別變數參考到子類別物件後,即透過父類別變數來存取子類別與父類別同時擁有的資料成員、方法成員。
l 以抽象類別實作多型:
package testPackage;
abstract class testAbstract{
abstract void showData();
}
class glaceon extends testAbstract{
public void showData(){
System.out.println("Glaceon: HP65, Atk60, Def110, SpA130, SpD130, Spe65");
}
}
class leafeon extends testAbstract{
public void showData(){
System.out.println("Leafeon: HP65, Atk110, Def130, SpA60, SpD65, Spe95");
}
}
public class test{
public static void main(String[] args){
// 宣告testAbstract抽象類別的baseStats參考變數
testAbstract baseStats;
glaceon iceEevee = new glaceon();
baseStats = iceEevee;
baseStats.showData();
leafeon grassEevee = new leafeon();
baseStats = grassEevee;
baseStats.showData();
}
}
package testPackage;
abstract class testAbstract{
abstract void showData();
}
class glaceon extends testAbstract{
public void showData(){
System.out.println("Glaceon: HP65, Atk60, Def110, SpA130, SpD130, Spe65");
}
}
class leafeon extends testAbstract{
public void showData(){
System.out.println("Leafeon: HP65, Atk110, Def130, SpA60, SpD65, Spe95");
}
}
public class test{
public static void main(String[] args){
// 宣告testAbstract抽象類別的baseStats參考變數
testAbstract baseStats;
glaceon iceEevee = new glaceon();
baseStats = iceEevee;
baseStats.showData();
leafeon grassEevee = new leafeon();
baseStats = grassEevee;
baseStats.showData();
}
}
l 以介面實作多型:
package testPackage;
interface testInterface{
void showData();
}
class glaceon implements testInterface{
public void showData(){
System.out.println("Glaceon: HP65, Atk60, Def110, SpA130, SpD130, Spe65");
}
}
class leafeon implements testInterface{
public void showData(){
System.out.println("Leafeon: HP65, Atk110, Def130, SpA60, SpD65, Spe95");
}
}
public class test{
public static void main(String[] args){
// 宣告testInterface介面的baseStats參考變數
testInterface baseStats;
glaceon iceEevee = new glaceon();
baseStats = iceEevee;
baseStats.showData();
leafeon grassEevee = new leafeon();
baseStats = grassEevee;
baseStats.showData();
}
}
package testPackage;
interface testInterface{
void showData();
}
class glaceon implements testInterface{
public void showData(){
System.out.println("Glaceon: HP65, Atk60, Def110, SpA130, SpD130, Spe65");
}
}
class leafeon implements testInterface{
public void showData(){
System.out.println("Leafeon: HP65, Atk110, Def130, SpA60, SpD65, Spe95");
}
}
public class test{
public static void main(String[] args){
// 宣告testInterface介面的baseStats參考變數
testInterface baseStats;
glaceon iceEevee = new glaceon();
baseStats = iceEevee;
baseStats.showData();
leafeon grassEevee = new leafeon();
baseStats = grassEevee;
baseStats.showData();
}
}
套件(Package)
l 一個.java檔只能定義一個套件名稱,只要是屬於testPackage套件的類別,就要放在testPackage資料夾裡面。
l 類別存取修飾子在不同套件的存取權限-public、不宣告(預設):
public表示該類別可以在不同套件存取。
預設階層表示該類別只能在相同套件存取。
public表示該類別可以在不同套件存取。
預設階層表示該類別只能在相同套件存取。
l 成員存取修飾子在不同套件的存取權限-private、protected、public、不宣告(預設):
private表示該成員在不同套件,沒有繼承權限,沒有使用權限。
private表示該成員在相同套件,沒有繼承權限,沒有使用權限。
protected表示該成員在不同套件,有繼承權限,沒有使用權限。
protected表示該成員在相同套件,有繼承權限,有使用權限。
public表示該成員在不同套件,有繼承權限,有使用權限。
public表示該成員在相同套件,有繼承權限,有使用權限。
預設階層表示該成員在不同套件,沒有繼承權限,沒有使用權限。
預設階層表示該成員在相同套件,有繼承權限,有使用權限。
private表示該成員在不同套件,沒有繼承權限,沒有使用權限。
private表示該成員在相同套件,沒有繼承權限,沒有使用權限。
protected表示該成員在不同套件,有繼承權限,沒有使用權限。
protected表示該成員在相同套件,有繼承權限,有使用權限。
public表示該成員在不同套件,有繼承權限,有使用權限。
public表示該成員在相同套件,有繼承權限,有使用權限。
預設階層表示該成員在不同套件,沒有繼承權限,沒有使用權限。
預設階層表示該成員在相同套件,有繼承權限,有使用權限。
二、例外處理
例外處理的語法
l 語法:
try{
檢查是否發生例外的程式區塊}
catch (例外類別 變數名稱){
例外發生時執行的程式區塊}
finally{
絕對會執行的程式區塊}
try{
檢查是否發生例外的程式區塊}
catch (例外類別 變數名稱){
例外發生時執行的程式區塊}
finally{
絕對會執行的程式區塊}
l catch:
用以抓取例外,可以使用一個catch敘述,亦可使用多個catch敘述。
用以抓取例外,可以使用一個catch敘述,亦可使用多個catch敘述。
l 例外類別:
所有的例外類別都是內建類別Throwable的子類別,Throwable是例外類別中的最上層,由它延伸出Error類別和Exception類別,其中Exception類別可用來捕捉不確定的例外;Exception類別又可以再延伸出RuntimeException類別,RuntimeException類別屬於執行時期發生的例外。
所有的例外類別都是內建類別Throwable的子類別,Throwable是例外類別中的最上層,由它延伸出Error類別和Exception類別,其中Exception類別可用來捕捉不確定的例外;Exception類別又可以再延伸出RuntimeException類別,RuntimeException類別屬於執行時期發生的例外。
l finally:
不一定需要用到finally,finally用在無論是否執行catch例外情況,最後皆須執行的程式區塊。
不一定需要用到finally,finally用在無論是否執行catch例外情況,最後皆須執行的程式區塊。
l 範例:
package testPackage;
public class test{
public static void main(String[] args){
try{
// 字串無法轉換成整數
int a = Integer.parseInt("Hello World");}
catch (ArithmeticException e){
System.out.println("Arithmetic Exception: " + e.toString());}
// 只能在最後一個catch使用(Exception e){...}捕捉不確定的例外
catch (Exception e){
System.out.println("Exception: " + e.toString());}
finally{
System.out.println("Hello World");}
}
}
package testPackage;
public class test{
public static void main(String[] args){
try{
// 字串無法轉換成整數
int a = Integer.parseInt("Hello World");}
catch (ArithmeticException e){
System.out.println("Arithmetic Exception: " + e.toString());}
// 只能在最後一個catch使用(Exception e){...}捕捉不確定的例外
catch (Exception e){
System.out.println("Exception: " + e.toString());}
finally{
System.out.println("Hello World");}
}
}
自行拋出例外
l 使用throw拋出例外:
package testPackage;
public class test{
static void divide(int a, int b){
try{
if (b == 0){
// 自行抛出Throwable類別或其子類別的例外物件
throw new ArithmeticException("Divisor Is 0");}
System.out.println(a + " / " + b + " = " + (a / b));}
catch (ArithmeticException e){
// getMessage()方法傳回使用new建立物件建構式之引數值
System.out.println("Arithmetic Exception: " + e.getMessage());
// toString()方法傳回引數值與例外字串物件
System.out.println("Arithmetic Exception: " + e.toString());}
}
public static void main(String[] args){
divide(6, 3);
divide(6, 0);
}
}
package testPackage;
public class test{
static void divide(int a, int b){
try{
if (b == 0){
// 自行抛出Throwable類別或其子類別的例外物件
throw new ArithmeticException("Divisor Is 0");}
System.out.println(a + " / " + b + " = " + (a / b));}
catch (ArithmeticException e){
// getMessage()方法傳回使用new建立物件建構式之引數值
System.out.println("Arithmetic Exception: " + e.getMessage());
// toString()方法傳回引數值與例外字串物件
System.out.println("Arithmetic Exception: " + e.toString());}
}
public static void main(String[] args){
divide(6, 3);
divide(6, 0);
}
}
l 使用throws宣告該方法可以拋出例外:
package testPackage;
public class test{
static void divide(int a, int b) throws ArithmeticException{
if (b == 0){
throw new ArithmeticException("Divisor Is 0");}
System.out.println(a + " / " + b + " = " + (a / b));
}
public static void main(String[] args){
try{
divide(6, 3);
divide(6, 0);}
catch (ArithmeticException e){
System.out.println("Arithmetic Exception: " + e.getMessage());
System.out.println("Arithmetic Exception: " + e.toString());}
}
}
package testPackage;
public class test{
static void divide(int a, int b) throws ArithmeticException{
if (b == 0){
throw new ArithmeticException("Divisor Is 0");}
System.out.println(a + " / " + b + " = " + (a / b));
}
public static void main(String[] args){
try{
divide(6, 3);
divide(6, 0);}
catch (ArithmeticException e){
System.out.println("Arithmetic Exception: " + e.getMessage());
System.out.println("Arithmetic Exception: " + e.toString());}
}
}
自訂例外類別
l 繼承Exception類別後,可以覆寫Throwable類別的方法成員,並定義自己所需的例外訊息。
l 範例:
package testPackage;
class customizedException extends Exception{
public String showMessage(){
return "showMessage() Is Overrided by Customized Method";
}
}
public class test{
static void divide(int a, int b){
try{
if (b == 0){
throw new customizedException();}
System.out.println(a + " / " + b + " = " + (a / b));}
catch (customizedException e){
System.out.println("Customized Exception: " + e.showMessage());}
}
public static void main(String[] args){
divide(6, 3);
divide(6, 0);
}
}
package testPackage;
class customizedException extends Exception{
public String showMessage(){
return "showMessage() Is Overrided by Customized Method";
}
}
public class test{
static void divide(int a, int b){
try{
if (b == 0){
throw new customizedException();}
System.out.println(a + " / " + b + " = " + (a / b));}
catch (customizedException e){
System.out.println("Customized Exception: " + e.showMessage());}
}
public static void main(String[] args){
divide(6, 3);
divide(6, 0);
}
}
三、集合與泛型
集合物件架構(Collections Framework)
l 使用前必須載入:import java.util.*;。
l 集合介面,下層介面繼承上層介面:
Collection >Set >SortedSet
>List
Map >SortedMap
Collection >Set >SortedSet
>List
Map >SortedMap
l 實作集合介面的具體類別及其特性:
集合介面 具體類別 集合物件的特性
Set HashSet 唯一性
SortedSet TreeSet 唯一性、排序性
List ArrayList、LinkedList 循序性
Map HashMap 鍵值對應
SortedMap TreeMap 鍵值對應、排序性
集合介面 具體類別 集合物件的特性
Set HashSet 唯一性
SortedSet TreeSet 唯一性、排序性
List ArrayList、LinkedList 循序性
Map HashMap 鍵值對應
SortedMap TreeMap 鍵值對應、排序性
l 建立集合物件的語法及範例:
// 具體類別名稱<資料型別> 集合物件名稱 = new 具體類別名稱<>();
HashSet<Integer> aObj = new HashSet<>();
// 集合介面名稱<資料型別> 集合物件名稱 = new 具體類別名稱<>();
Set<Integer> bObj = new HashSet<>();
Collection<Integer> cObj = new HashSet<>();
// 具體類別名稱<資料型別> 集合物件名稱 = new 具體類別名稱<>();
HashSet<Integer> aObj = new HashSet<>();
// 集合介面名稱<資料型別> 集合物件名稱 = new 具體類別名稱<>();
Set<Integer> bObj = new HashSet<>();
Collection<Integer> cObj = new HashSet<>();
Collection<資料型別>介面
l Collection<資料型別>介面常用的方法成員:
// Collection<String> aObj = new HashSet<>();
// Collection<String> bObj = new HashSet<>();
// 集合物件是空的,傳回true
System.out.println(aObj.isEmpty());
// 指定物件的元素新增為元素,若成功則傳回true
System.out.println(aObj.add("Hello World"));
// 指定集合物件的所有元素新增為元素,若成功則傳回true
System.out.println(aObj.addAll(bObj));
// 傳回集合物件元素個數
System.out.println(aObj.size());
// 集合物件包含指定物件的元素,傳回true
System.out.println(aObj.contains("Hello World"));
// 集合物件包含指定集合物件的所有元素,傳回true
System.out.println(aObj.containsAll(bObj));
// 移除指定物件的元素,若成功則傳回true
System.out.println(aObj.remove("Hello World"));
// 移除指定集合物件的所有元素,若成功則傳回true
System.out.println(aObj.removeAll(bObj));
// 僅保留集合物件的元素,其餘皆移除,若成功則傳回true
System.out.println(aObj.retainAll(bObj));
// 指定物件與集合物件相同,傳回true
System.out.println(aObj.equals(bObj));
// 移除集合物件的所有元素
aObj.clear();
// Collection<String> aObj = new HashSet<>();
// Collection<String> bObj = new HashSet<>();
// 集合物件是空的,傳回true
System.out.println(aObj.isEmpty());
// 指定物件的元素新增為元素,若成功則傳回true
System.out.println(aObj.add("Hello World"));
// 指定集合物件的所有元素新增為元素,若成功則傳回true
System.out.println(aObj.addAll(bObj));
// 傳回集合物件元素個數
System.out.println(aObj.size());
// 集合物件包含指定物件的元素,傳回true
System.out.println(aObj.contains("Hello World"));
// 集合物件包含指定集合物件的所有元素,傳回true
System.out.println(aObj.containsAll(bObj));
// 移除指定物件的元素,若成功則傳回true
System.out.println(aObj.remove("Hello World"));
// 移除指定集合物件的所有元素,若成功則傳回true
System.out.println(aObj.removeAll(bObj));
// 僅保留集合物件的元素,其餘皆移除,若成功則傳回true
System.out.println(aObj.retainAll(bObj));
// 指定物件與集合物件相同,傳回true
System.out.println(aObj.equals(bObj));
// 移除集合物件的所有元素
aObj.clear();
Set<資料型別>介面與HashSet<資料型別>類別
l HashSet<資料型別>類別常用的建構式:
// 建立一個全新的空HashSet物件,預設元素個數為16個
Set<String> aObj = new HashSet<>();
// 建立一個全新的空HashSet物件,指定元素個數為10個
Set<String> bObj = new HashSet<>(10);
// 建立一個含指定物件bObj的HashSet物件
Set<String> cObj = new HashSet<>(bObj);
// 建立一個全新的空HashSet物件,預設元素個數為16個
Set<String> aObj = new HashSet<>();
// 建立一個全新的空HashSet物件,指定元素個數為10個
Set<String> bObj = new HashSet<>(10);
// 建立一個含指定物件bObj的HashSet物件
Set<String> cObj = new HashSet<>(bObj);
SortedSet<資料型別>介面與TreeSet<資料型別>類別
l SortedSet<資料型別>介面常用的方法成員:
// SortedSet<Integer> aObj = new TreeSet<>();
// 傳回集合物件第一個元素
System.out.println(aObj.first());
// 傳回集合物件最後一個元素
System.out.println(aObj.last());
// 傳回集合物件中值小於16的所有元素資料
System.out.println(aObj.headSet(16));
// 傳回集合物件中值大於等於85的所有元素資料
System.out.println(aObj.tailSet(85));
// 傳回集合物件中值大於等於16,且小於85的所有元素資料
System.out.println(aObj.subSet(16, 85));
// SortedSet<Integer> aObj = new TreeSet<>();
// 傳回集合物件第一個元素
System.out.println(aObj.first());
// 傳回集合物件最後一個元素
System.out.println(aObj.last());
// 傳回集合物件中值小於16的所有元素資料
System.out.println(aObj.headSet(16));
// 傳回集合物件中值大於等於85的所有元素資料
System.out.println(aObj.tailSet(85));
// 傳回集合物件中值大於等於16,且小於85的所有元素資料
System.out.println(aObj.subSet(16, 85));
l TreeSet<資料型別>類別常用的建構式:
// 建立一個全新的空TreeSet物件,元素由小到大排序
SortedSet<String> aObj = new TreeSet<>();
// 建立一個含指定物件aObj的TreeSet物件
SortedSet<String> bObj = new TreeSet<>(aObj);
// 建立一個全新的空TreeSet物件,元素由小到大排序
SortedSet<String> aObj = new TreeSet<>();
// 建立一個含指定物件aObj的TreeSet物件
SortedSet<String> bObj = new TreeSet<>(aObj);
List<資料型別>介面與ArrayList<資料型別>、LinkedList<資料型別>類別
l List<資料型別>介面常用的方法成員:
// List<Integer> aObj = new ArrayList<>();
// List<Integer> bObj = new ArrayList<>();
// 指定物件的元素新增為元素至尾部,若成功則傳回true
System.out.println(aObj.add(200));
// 指定物件的元素新增為元素至索引位置
aObj.add(0, 300);
// 指定集合物件的所有元素新增為元素至尾部,若成功則傳回true
System.out.println(aObj.addAll(bObj));
// 指定集合物件的所有元素新增為元素至索引位置,若成功則傳回true
System.out.println(aObj.addAll(1, bObj));
// 傳回索引位置的元素
System.out.println(aObj.get(4));
// 傳回第一次出現指定元素的索引位置,若不包含該元素則傳回-1
System.out.println(aObj.indexOf(8));
// 傳回最後出現指定元素的索引位置,若不包含該元素則傳回-1
System.out.println(aObj.lastIndexOf(8));
// 傳回索引位置包括1到索引位置不包括4之間的集合
System.out.println(aObj.subList(1, 4));
// 移除指定索引位置的元素,傳回被移除的元素
System.out.println(aObj.remove(4));
// 替換指定索引位置的元素,傳回被替換的元素
System.out.println(aObj.set(0, 400));
// List<Integer> aObj = new ArrayList<>();
// List<Integer> bObj = new ArrayList<>();
// 指定物件的元素新增為元素至尾部,若成功則傳回true
System.out.println(aObj.add(200));
// 指定物件的元素新增為元素至索引位置
aObj.add(0, 300);
// 指定集合物件的所有元素新增為元素至尾部,若成功則傳回true
System.out.println(aObj.addAll(bObj));
// 指定集合物件的所有元素新增為元素至索引位置,若成功則傳回true
System.out.println(aObj.addAll(1, bObj));
// 傳回索引位置的元素
System.out.println(aObj.get(4));
// 傳回第一次出現指定元素的索引位置,若不包含該元素則傳回-1
System.out.println(aObj.indexOf(8));
// 傳回最後出現指定元素的索引位置,若不包含該元素則傳回-1
System.out.println(aObj.lastIndexOf(8));
// 傳回索引位置包括1到索引位置不包括4之間的集合
System.out.println(aObj.subList(1, 4));
// 移除指定索引位置的元素,傳回被移除的元素
System.out.println(aObj.remove(4));
// 替換指定索引位置的元素,傳回被替換的元素
System.out.println(aObj.set(0, 400));
l ArrayList<資料型別>類別常用的建構式:
// ArrayList不用事先宣告元素數量,是可以自行調整大小的動態串列
// 建立一個全新的空ArrayList物件,預設元素個數為10個
List<String> aObj = new ArrayList<>();
// 建立一個全新的空ArrayList物件,指定元素個數為20個
List<String> bObj = new ArrayList<>(20);
// 建立一個含指定物件bObj的ArrayList物件
List<String> cObj = new ArrayList<>(bObj);
// ArrayList不用事先宣告元素數量,是可以自行調整大小的動態串列
// 建立一個全新的空ArrayList物件,預設元素個數為10個
List<String> aObj = new ArrayList<>();
// 建立一個全新的空ArrayList物件,指定元素個數為20個
List<String> bObj = new ArrayList<>(20);
// 建立一個含指定物件bObj的ArrayList物件
List<String> cObj = new ArrayList<>(bObj);
l ArrayList<資料型別>類別常用的方法成員:
// ArrayList<Integer> aObj = new ArrayList<>();
// 增加此ArrayList集合物件的容量
aObj.ensureCapacity(50);
// 調整此ArrayList集合物件的容量為串列目前大小
aObj.trimToSize();
// ArrayList<Integer> aObj = new ArrayList<>();
// 增加此ArrayList集合物件的容量
aObj.ensureCapacity(50);
// 調整此ArrayList集合物件的容量為串列目前大小
aObj.trimToSize();
l LinkedList<資料型別>類別常用的建構式:
// LinkedList將元素視為節點,每個節點皆有資料欄與鏈結欄
// 建立一個全新的空LinkedList物件
List<String> aObj = new LinkedList<>();
// 建立一個含指定物件aObj的LinkedList物件
List<String> bObj = new LinkedList<>(aObj);
// LinkedList將元素視為節點,每個節點皆有資料欄與鏈結欄
// 建立一個全新的空LinkedList物件
List<String> aObj = new LinkedList<>();
// 建立一個含指定物件aObj的LinkedList物件
List<String> bObj = new LinkedList<>(aObj);
l LinkedList<資料型別>類別常用的方法成員:
// LinkedList<Integer> aObj = new LinkedList<>();
// 將指定元素插入鏈結串列開頭,其指標值重新排序
aObj.addFirst(25);
// 將指定元素插入鏈結串列尾端
aObj.addLast(50);
// 移除並傳回鏈結串列的第一個元素
System.out.println(aObj.removeFirst());
// 移除並傳回鏈結串列的最後一個元素
System.out.println(aObj.removeLast());
// 傳回鏈結串列的第一個元素
System.out.println(aObj.getFirst());
// 傳回鏈結串列的最後一個元素
System.out.println(aObj.getLast());
// LinkedList<Integer> aObj = new LinkedList<>();
// 將指定元素插入鏈結串列開頭,其指標值重新排序
aObj.addFirst(25);
// 將指定元素插入鏈結串列尾端
aObj.addLast(50);
// 移除並傳回鏈結串列的第一個元素
System.out.println(aObj.removeFirst());
// 移除並傳回鏈結串列的最後一個元素
System.out.println(aObj.removeLast());
// 傳回鏈結串列的第一個元素
System.out.println(aObj.getFirst());
// 傳回鏈結串列的最後一個元素
System.out.println(aObj.getLast());
Map<K, V>介面與HashMap<K, V>類別
l Map<K, V>介面常用的方法成員:
// Map<String, String> aObj = new HashMap<>();
// Map<String, String> bObj = new HashMap<>();
// 集合物件是空的,傳回true
System.out.println(aObj.isEmpty());
// 將關鍵值K與對應值V新增至集合物件
aObj.put("Sylveon", "Fairy");
// 將指定的Map集合物件新增至目前的Map集合物件
aObj.putAll(bObj);
// 傳回集合物件元素個數
System.out.println(aObj.size());
// 集合物件包含指定關鍵值K,傳回true
System.out.println(aObj.containsKey("Sylveon"));
// 集合物件包含指定對應值V,傳回true
System.out.println(aObj.containsValue("Fairy"));
// 傳回集合物件中指定關鍵值K的對應值V
System.out.println(aObj.get("Sylveon"));
// 將所有關鍵值K傳回,並轉換成實作Set介面的集合物件
System.out.println(aObj.keySet());
// 將所有對應值V傳回,並轉換成實作Collection介面的集合物件
System.out.println(aObj.values());
// 移除集合物件中指定關鍵值K,若成功則傳回的對應值V
System.out.println(aObj.remove("Sylveon"));
// 移除集合物件的所有元素
aObj.clear();
// Map<String, String> aObj = new HashMap<>();
// Map<String, String> bObj = new HashMap<>();
// 集合物件是空的,傳回true
System.out.println(aObj.isEmpty());
// 將關鍵值K與對應值V新增至集合物件
aObj.put("Sylveon", "Fairy");
// 將指定的Map集合物件新增至目前的Map集合物件
aObj.putAll(bObj);
// 傳回集合物件元素個數
System.out.println(aObj.size());
// 集合物件包含指定關鍵值K,傳回true
System.out.println(aObj.containsKey("Sylveon"));
// 集合物件包含指定對應值V,傳回true
System.out.println(aObj.containsValue("Fairy"));
// 傳回集合物件中指定關鍵值K的對應值V
System.out.println(aObj.get("Sylveon"));
// 將所有關鍵值K傳回,並轉換成實作Set介面的集合物件
System.out.println(aObj.keySet());
// 將所有對應值V傳回,並轉換成實作Collection介面的集合物件
System.out.println(aObj.values());
// 移除集合物件中指定關鍵值K,若成功則傳回的對應值V
System.out.println(aObj.remove("Sylveon"));
// 移除集合物件的所有元素
aObj.clear();
l HashMap<K, V>類別常用的建構式:
// 建立一個全新的空HashMap物件,預設元素個數為16個
Map<String, String> aObj = new HashMap<>();
// 建立一個全新的空HashMap物件,指定元素個數為10個
Map<String, String> bObj = new HashMap<>(10);
// 建立一個含指定物件bObj的HashMap物件
Map<String, String> cObj = new HashMap<>(bObj);
// 建立一個全新的空HashMap物件,預設元素個數為16個
Map<String, String> aObj = new HashMap<>();
// 建立一個全新的空HashMap物件,指定元素個數為10個
Map<String, String> bObj = new HashMap<>(10);
// 建立一個含指定物件bObj的HashMap物件
Map<String, String> cObj = new HashMap<>(bObj);
SortedMap<K, V>介面與TreeMap類別
l SortedMap<K, V>介面常用的方法成員:
// SortedMap<String, String> aObj = new TreeMap<>();
// 傳回集合物件第一個元素的關鍵值K
System.out.println(aObj.firstKey());
// 傳回集合物件最後一個元素的關鍵值K
System.out.println(aObj.lastKey());
// 傳回集合物件中關鍵值K小於G的所有元素資料
System.out.println(aObj.headMap("G"));
// 傳回集合物件中關鍵值K大於等於R的所有元素資料
System.out.println(aObj.tailMap("R"));
// 傳回集合物件中關鍵值K大於等於G,且小於R的所有元素資料
System.out.println(aObj.subMap("G", "R"));
// SortedMap<String, String> aObj = new TreeMap<>();
// 傳回集合物件第一個元素的關鍵值K
System.out.println(aObj.firstKey());
// 傳回集合物件最後一個元素的關鍵值K
System.out.println(aObj.lastKey());
// 傳回集合物件中關鍵值K小於G的所有元素資料
System.out.println(aObj.headMap("G"));
// 傳回集合物件中關鍵值K大於等於R的所有元素資料
System.out.println(aObj.tailMap("R"));
// 傳回集合物件中關鍵值K大於等於G,且小於R的所有元素資料
System.out.println(aObj.subMap("G", "R"));
l TreeMap<K, V>類別常用的建構式:
// 建立一個全新的空TreeMap物件,元素依關鍵值K由小到大排序
SortedMap<String, String> aObj = new TreeMap<>();
// 建立一個含指定物件aObj的TreeMap物件
SortedMap<String, String> bObj = new TreeMap<>(aObj);
// 建立一個全新的空TreeMap物件,元素依關鍵值K由小到大排序
SortedMap<String, String> aObj = new TreeMap<>();
// 建立一個含指定物件aObj的TreeMap物件
SortedMap<String, String> bObj = new TreeMap<>(aObj);
Collections集合工具類別
l Collections為Collection介面的工具類別,該類別中的方法成員皆採static靜態方法。
l 範例:
package testPackage;
import java.util.*;
public class test{
public static void main(String[] args){
List<Integer> aObj = new ArrayList<>();
for (int i = 1; i < 100; i += 7){
aObj.add(i);}
// 對集合物件的元素做反轉順序的排列
Collections.reverse(aObj);
System.out.println(aObj);
// 對集合物件的元素做由小到大的排列
Collections.sort(aObj);
System.out.println(aObj);
// 將集合物件中指定位置的元素交換
Collections.swap(aObj, 0, 1);
System.out.println(aObj);
// 傳回集合物件的最大元素
System.out.println(Collections.max(aObj));
// 傳回集合物件的最小元素
System.out.println(Collections.min(aObj));
// 使用指定資料替換集合物件的所有元素
Collections.fill(aObj, 11);
System.out.println(aObj);
}
}
package testPackage;
import java.util.*;
public class test{
public static void main(String[] args){
List<Integer> aObj = new ArrayList<>();
for (int i = 1; i < 100; i += 7){
aObj.add(i);}
// 對集合物件的元素做反轉順序的排列
Collections.reverse(aObj);
System.out.println(aObj);
// 對集合物件的元素做由小到大的排列
Collections.sort(aObj);
System.out.println(aObj);
// 將集合物件中指定位置的元素交換
Collections.swap(aObj, 0, 1);
System.out.println(aObj);
// 傳回集合物件的最大元素
System.out.println(Collections.max(aObj));
// 傳回集合物件的最小元素
System.out.println(Collections.min(aObj));
// 使用指定資料替換集合物件的所有元素
Collections.fill(aObj, 11);
System.out.println(aObj);
}
}
集合的走訪器
l Iterator<資料型別>介面:
只要能實作Collection支系介面的集合物件皆可實作Iterator介面,Iterator的資料型別需與集合物件的資料型別相同。
只要能實作Collection支系介面的集合物件皆可實作Iterator介面,Iterator的資料型別需與集合物件的資料型別相同。
l Iterator<資料型別>介面常用的方法成員:
package testPackage;
import java.util.*;
public class test{
public static void main(String[] args){
SortedSet<Integer> aObj = new TreeSet<>();
for (int i = 1; i <= 40; i++){
aObj.add(i);}
// 建立走訪器物件aItera
Iterator<Integer> aItera = aObj.iterator();
// 傳回Iterator目前指向的元素
System.out.println(aItera.next());
// 刪除Iterator目前指向的元素
aItera.remove();
// 集合還有Iterator指向的下個元素,傳回true
while (aItera.hasNext()){
int num = aItera.next();
for (int j = 2; j < num; j++){
if (num % j == 0){
aItera.remove();
break;}}}
System.out.println("Prime Number between 1 & 40: " + aObj);
}
}
package testPackage;
import java.util.*;
public class test{
public static void main(String[] args){
SortedSet<Integer> aObj = new TreeSet<>();
for (int i = 1; i <= 40; i++){
aObj.add(i);}
// 建立走訪器物件aItera
Iterator<Integer> aItera = aObj.iterator();
// 傳回Iterator目前指向的元素
System.out.println(aItera.next());
// 刪除Iterator目前指向的元素
aItera.remove();
// 集合還有Iterator指向的下個元素,傳回true
while (aItera.hasNext()){
int num = aItera.next();
for (int j = 2; j < num; j++){
if (num % j == 0){
aItera.remove();
break;}}}
System.out.println("Prime Number between 1 & 40: " + aObj);
}
}
l ListIterator<資料型別>介面:
ListIterator介面繼承Iterator介面;Iterator介面物件的走訪方式是單向的,ListIterator介面物件則是雙向的;Iterator介面物件只能讀取與刪除元素,ListIterator介面物件則可以讀取、刪除、新增與修改元素。
ListIterator介面繼承Iterator介面;Iterator介面物件的走訪方式是單向的,ListIterator介面物件則是雙向的;Iterator介面物件只能讀取與刪除元素,ListIterator介面物件則可以讀取、刪除、新增與修改元素。
l ListIterator<資料型別>介面常用的方法成員:
package testPackage;
import java.util.*;
public class test{
public static void main(String[] args){
List<String> aObj = new ArrayList<>();
String[] gem = {"Ruby", "Sapphire", "Emerald"};
for (String i : gem){
aObj.add(i);}
ListIterator<String> aItera = aObj.listIterator();
// 集合還有ListIterator指向的下個元素,傳回true
while (aItera.hasNext()){
// 傳回ListIterator目前指向的元素
System.out.print(aItera.next());
// 傳回ListIterator目前指向的元素的索引值
System.out.println(aItera.nextIndex());
if (aItera.nextIndex() == 3){
// 在ListIterator指向的元素置換元素資料
aItera.set("Platinum");}}
// 集合還有ListIterator指向的前個元素,傳回true
while (aItera.hasPrevious()){
// 傳回ListIterator目前指向的元素
System.out.print(aItera.previous());
// 傳回ListIterator目前指向的元素的索引值
System.out.println(aItera.previousIndex());
if (aItera.previousIndex() == 1){
// 刪除ListIterator目前指向的元素
aItera.remove();}}
aItera = aObj.listIterator(2);
// 在ListIterator指向的元素前加入元素資料
aItera.add("Emerald");
System.out.println(aObj);
}
}
package testPackage;
import java.util.*;
public class test{
public static void main(String[] args){
List<String> aObj = new ArrayList<>();
String[] gem = {"Ruby", "Sapphire", "Emerald"};
for (String i : gem){
aObj.add(i);}
ListIterator<String> aItera = aObj.listIterator();
// 集合還有ListIterator指向的下個元素,傳回true
while (aItera.hasNext()){
// 傳回ListIterator目前指向的元素
System.out.print(aItera.next());
// 傳回ListIterator目前指向的元素的索引值
System.out.println(aItera.nextIndex());
if (aItera.nextIndex() == 3){
// 在ListIterator指向的元素置換元素資料
aItera.set("Platinum");}}
// 集合還有ListIterator指向的前個元素,傳回true
while (aItera.hasPrevious()){
// 傳回ListIterator目前指向的元素
System.out.print(aItera.previous());
// 傳回ListIterator目前指向的元素的索引值
System.out.println(aItera.previousIndex());
if (aItera.previousIndex() == 1){
// 刪除ListIterator目前指向的元素
aItera.remove();}}
aItera = aObj.listIterator(2);
// 在ListIterator指向的元素前加入元素資料
aItera.add("Emerald");
System.out.println(aObj);
}
}
四、多執行緒
Thread類別
l Thread類別常用的建構式:
// 建立一個空的Thread物件,啟動執行緒時會執行Thread的run()方法
public Thread()
// 引數name用來設定執行緒物件的名稱
public Thread(String name)
// 引數target是用來實作Runnable介面物件
public Thread(Runnable target)
// 同時傳入實作Runnable介面物件,與設定執行緒物件的名稱
public Thread(Runnable target, String name)
// 建立一個空的Thread物件,啟動執行緒時會執行Thread的run()方法
public Thread()
// 引數name用來設定執行緒物件的名稱
public Thread(String name)
// 引數target是用來實作Runnable介面物件
public Thread(Runnable target)
// 同時傳入實作Runnable介面物件,與設定執行緒物件的名稱
public Thread(Runnable target, String name)
l Thread類別常用的方法成員:
package testPackage;
class testThread extends Thread{
// 覆寫Thread類別的run()方法,要執行的程式碼置於此
public void run(){
try{
for (int i = 1; i <= 5; i++){
// 取得執行緒的名稱
System.out.println(getName() + ": " + i);
// 使用sleep()必須捕捉例外
sleep(1000);}}
catch (InterruptedException e){
e.printStackTrace();}
}
}
public class test{
public static void main(String[] args){
testThread aObj = new testThread();
// 設定執行緒的名稱
aObj.setName("Thread A");
// 設定執行緒的優先權,設定值為1至10,數值越大優先權越高
aObj.setPriority(6);
// 取得執行緒的優先權
System.out.println(aObj.getPriority());
aObj.setPriority(Thread.MAX_PRIORITY);
System.out.println(aObj.getPriority());
aObj.setPriority(Thread.MIN_PRIORITY);
System.out.println(aObj.getPriority());
aObj.setPriority(Thread.NORM_PRIORITY);
System.out.println(aObj.getPriority());
// 啟動執行緒
aObj.start();
// 取得目前執行緒的參考變數值,例如目前執行緒的名稱
System.out.println(Thread.currentThread().getName());
try{
// 等待執行緒終止,才會繼續執行join()方法後的程式
// 使用join()必須捕捉例外
aObj.join();}
catch (InterruptedException e){
e.printStackTrace();}
// 取得執行緒是否存活
System.out.println(aObj.isAlive());
}
}
package testPackage;
class testThread extends Thread{
// 覆寫Thread類別的run()方法,要執行的程式碼置於此
public void run(){
try{
for (int i = 1; i <= 5; i++){
// 取得執行緒的名稱
System.out.println(getName() + ": " + i);
// 使用sleep()必須捕捉例外
sleep(1000);}}
catch (InterruptedException e){
e.printStackTrace();}
}
}
public class test{
public static void main(String[] args){
testThread aObj = new testThread();
// 設定執行緒的名稱
aObj.setName("Thread A");
// 設定執行緒的優先權,設定值為1至10,數值越大優先權越高
aObj.setPriority(6);
// 取得執行緒的優先權
System.out.println(aObj.getPriority());
aObj.setPriority(Thread.MAX_PRIORITY);
System.out.println(aObj.getPriority());
aObj.setPriority(Thread.MIN_PRIORITY);
System.out.println(aObj.getPriority());
aObj.setPriority(Thread.NORM_PRIORITY);
System.out.println(aObj.getPriority());
// 啟動執行緒
aObj.start();
// 取得目前執行緒的參考變數值,例如目前執行緒的名稱
System.out.println(Thread.currentThread().getName());
try{
// 等待執行緒終止,才會繼續執行join()方法後的程式
// 使用join()必須捕捉例外
aObj.join();}
catch (InterruptedException e){
e.printStackTrace();}
// 取得執行緒是否存活
System.out.println(aObj.isAlive());
}
}
三種建立執行緒的方式
l 直接建立Thread類別執行緒物件:
package testPackage;
public class test{
public static void main(String[] args){
Thread tortoise = new Thread(){
public void run(){
for (int i = 1; i <= 10; i++){
System.out.println("Tortoise Runs " + i + " KM(s)");}
System.out.println("Tortoise Reaches the Finish Line");}
};
Thread rabbit = new Thread(){
public void run(){
for (int i = 3; i <= 10; i += 3){
if ((int)(Math.random() * 10 + 1) % 2 == 0){
i -= 3;
System.out.println("Rabbit Rests");}
else{
System.out.println("Rabbit Runs " + i + " KM(s)");}}
System.out.println("Rabbit Reaches the Finish Line");}
};
tortoise.start();
rabbit.start();
}
}
package testPackage;
public class test{
public static void main(String[] args){
Thread tortoise = new Thread(){
public void run(){
for (int i = 1; i <= 10; i++){
System.out.println("Tortoise Runs " + i + " KM(s)");}
System.out.println("Tortoise Reaches the Finish Line");}
};
Thread rabbit = new Thread(){
public void run(){
for (int i = 3; i <= 10; i += 3){
if ((int)(Math.random() * 10 + 1) % 2 == 0){
i -= 3;
System.out.println("Rabbit Rests");}
else{
System.out.println("Rabbit Runs " + i + " KM(s)");}}
System.out.println("Rabbit Reaches the Finish Line");}
};
tortoise.start();
rabbit.start();
}
}
l 宣告繼承Thread類別的自訂執行緒類別:
package testPackage;
class testThread extends Thread{
String threadName;
testThread(String name){
threadName = name;
// 啟動執行緒
start();
}
public void run(){
for (int i = 1; i <= 5; i++){
System.out.println(threadName + ": " + i);}
}
}
public class test{
public static void main(String[] args){
// 建立testThread類別的aObj物件
new testThread("Thread A");
new testThread("Thread B");
}
}
package testPackage;
class testThread extends Thread{
String threadName;
testThread(String name){
threadName = name;
// 啟動執行緒
start();
}
public void run(){
for (int i = 1; i <= 5; i++){
System.out.println(threadName + ": " + i);}
}
}
public class test{
public static void main(String[] args){
// 建立testThread類別的aObj物件
new testThread("Thread A");
new testThread("Thread B");
}
}
l 實作Runnable介面來建立執行緒:
package testPackage;
class testThread implements Runnable{
String threadName;
testThread(String name){
threadName = name;
}
public void run(){
for (int i = 1; i <= 5; i++){
System.out.println(threadName + ": " + i);}
}
}
public class test{
public static void main(String[] args){
// 建立Thread類別的準執行緒aObj物件
Thread aObj = new Thread(new testThread("Thread A"));
Thread bObj = new Thread(new testThread("Thread B"));
// 啟動執行緒
aObj.start();
bObj.start();
}
}
package testPackage;
class testThread implements Runnable{
String threadName;
testThread(String name){
threadName = name;
}
public void run(){
for (int i = 1; i <= 5; i++){
System.out.println(threadName + ": " + i);}
}
}
public class test{
public static void main(String[] args){
// 建立Thread類別的準執行緒aObj物件
Thread aObj = new Thread(new testThread("Thread A"));
Thread bObj = new Thread(new testThread("Thread B"));
// 啟動執行緒
aObj.start();
bObj.start();
}
}
執行緒的同步(Synchronized)
l 避免在同一時間,多個執行緒同時存取同一個物件而造成資料錯誤。
l 範例:
package testPackage;
class testThread extends Thread{
static int totalGold = 20000000;
int grabed;
String name;
testThread(String n){
grabed = 0;
name = n;
start();
}
private synchronized static boolean grabGold(){
if (totalGold > 0){
totalGold -= 1;
return true;}
else{
return false;}
}
public void run(){
while (grabGold() == true){
grabed += 1;}
System.out.println(name + " Digs Out " + grabed + " Nuggets");
}
}
public class test{
public static void main(String[] args){
System.out.println("There Are " + testThread.totalGold + " Nuggets");
new testThread("Timmy");
new testThread("Wendy");
new testThread("Mai");
}
}
package testPackage;
class testThread extends Thread{
static int totalGold = 20000000;
int grabed;
String name;
testThread(String n){
grabed = 0;
name = n;
start();
}
private synchronized static boolean grabGold(){
if (totalGold > 0){
totalGold -= 1;
return true;}
else{
return false;}
}
public void run(){
while (grabGold() == true){
grabed += 1;}
System.out.println(name + " Digs Out " + grabed + " Nuggets");
}
}
public class test{
public static void main(String[] args){
System.out.println("There Are " + testThread.totalGold + " Nuggets");
new testThread("Timmy");
new testThread("Wendy");
new testThread("Mai");
}
}
執行緒的等待和喚醒
l wait()、notify()和notifyAll()方法:
notify()方法喚醒一個等待中的執行緒。
notifyAll()方法喚醒所有等待中的執行緒。
wait()方法讓指定的執行緒成為等待狀態。
wait()方法須寫在synchronized敘述區段,並使用try...catch捕捉例外。
wait()方法須寫在迴圈,避免notify()和notifyAll()喚醒不該喚醒的執行緒。
notify()方法喚醒一個等待中的執行緒。
notifyAll()方法喚醒所有等待中的執行緒。
wait()方法讓指定的執行緒成為等待狀態。
wait()方法須寫在synchronized敘述區段,並使用try...catch捕捉例外。
wait()方法須寫在迴圈,避免notify()和notifyAll()喚醒不該喚醒的執行緒。
l 範例:
package testPackage;
class Frisbee{
private boolean isThrow = false;
public synchronized void throwF(int tNo){
while (isThrow){
try{
wait();}
catch (InterruptedException e){
e.printStackTrace();}}
System.out.println("Throw No." + tNo + " Frisbee");
isThrow = true;
notify();
}
public synchronized void accessF(int aNo){
while (!isThrow){
try{
wait();}
catch (InterruptedException e){
e.printStackTrace();}}
System.out.println("Access No." + aNo + " Frisbee");
isThrow = false;
notify();
}
}
class ThrowFrisbee extends Thread{
Frisbee frisbee;
ThrowFrisbee(Frisbee frisbee){
this.frisbee = frisbee;
}
public void run(){
for (int i = 1; i <= 5; i++){
frisbee.throwF(i);}
}
}
class AccessFrisbee extends Thread{
Frisbee frisbee;
AccessFrisbee(Frisbee frisbee){
this.frisbee = frisbee;
}
public void run(){
for (int i = 1; i <= 5; i++){
frisbee.accessF(i);}
}
}
public class test{
public static void main(String[] args){
Frisbee frisbee = new Frisbee();
ThrowFrisbee master = new ThrowFrisbee(frisbee);
AccessFrisbee dog = new AccessFrisbee(frisbee);
master.start();
dog.start();
}
}
package testPackage;
class Frisbee{
private boolean isThrow = false;
public synchronized void throwF(int tNo){
while (isThrow){
try{
wait();}
catch (InterruptedException e){
e.printStackTrace();}}
System.out.println("Throw No." + tNo + " Frisbee");
isThrow = true;
notify();
}
public synchronized void accessF(int aNo){
while (!isThrow){
try{
wait();}
catch (InterruptedException e){
e.printStackTrace();}}
System.out.println("Access No." + aNo + " Frisbee");
isThrow = false;
notify();
}
}
class ThrowFrisbee extends Thread{
Frisbee frisbee;
ThrowFrisbee(Frisbee frisbee){
this.frisbee = frisbee;
}
public void run(){
for (int i = 1; i <= 5; i++){
frisbee.throwF(i);}
}
}
class AccessFrisbee extends Thread{
Frisbee frisbee;
AccessFrisbee(Frisbee frisbee){
this.frisbee = frisbee;
}
public void run(){
for (int i = 1; i <= 5; i++){
frisbee.accessF(i);}
}
}
public class test{
public static void main(String[] args){
Frisbee frisbee = new Frisbee();
ThrowFrisbee master = new ThrowFrisbee(frisbee);
AccessFrisbee dog = new AccessFrisbee(frisbee);
master.start();
dog.start();
}
}
五、Lambda語法
匿名類別物件與Lambda語法
l Lambda語法常用於匿名(Anonymous)類別並實作方法的場合,以便讓Java語法更簡潔,通常用於只有一個public方法的介面。
l 自訂類別物件範例-不使用匿名類別物件、Lambda語法:
package testPackage;
import java.util.*;
class student{
public String name;
private int chi;
private int eng;
public student(String n, int c, int e){
name = n;
chi = c;
eng = e;
}
public int getSum(){
return (chi + eng);
}
}
class studentComparator implements Comparator<student>{
public int compare(student aObj, student bObj){
int a, b, returnValue = 0;
a = aObj.getSum();
b = bObj.getSum();
if (a > b){
returnValue = 1;}
else if (a == b){
returnValue = 0;}
else if (a < b){
returnValue = -1;}
return returnValue;
}
}
public class test{
public static void main(String[] args){
student[] allStu = {new student("aStudent", 54, 77), new student("bStudent", 88, 27), new student("cStudent", 83, 77), new student("dStudent", 66, 44)};
System.out.println("Before Sorting Sum:");
for (int i = allStu.length - 1; i >= 0; i--){
System.out.println(allStu[i].name);}
// Arrays.sort(要排序的物件陣列, 要排序的規則物件);
Arrays.sort(allStu, new studentComparator());
System.out.println("After Sorting Sum:");
for (int i = allStu.length - 1; i >= 0; i--){
System.out.println(allStu[i].name);}
}
}
package testPackage;
import java.util.*;
class student{
public String name;
private int chi;
private int eng;
public student(String n, int c, int e){
name = n;
chi = c;
eng = e;
}
public int getSum(){
return (chi + eng);
}
}
class studentComparator implements Comparator<student>{
public int compare(student aObj, student bObj){
int a, b, returnValue = 0;
a = aObj.getSum();
b = bObj.getSum();
if (a > b){
returnValue = 1;}
else if (a == b){
returnValue = 0;}
else if (a < b){
returnValue = -1;}
return returnValue;
}
}
public class test{
public static void main(String[] args){
student[] allStu = {new student("aStudent", 54, 77), new student("bStudent", 88, 27), new student("cStudent", 83, 77), new student("dStudent", 66, 44)};
System.out.println("Before Sorting Sum:");
for (int i = allStu.length - 1; i >= 0; i--){
System.out.println(allStu[i].name);}
// Arrays.sort(要排序的物件陣列, 要排序的規則物件);
Arrays.sort(allStu, new studentComparator());
System.out.println("After Sorting Sum:");
for (int i = allStu.length - 1; i >= 0; i--){
System.out.println(allStu[i].name);}
}
}
l 自訂類別物件範例-使用匿名類別物件、Lambda語法:
package testPackage;
import java.util.*;
class student{
public String name;
private int chi;
private int eng;
public student(String n, int c, int e){
name = n;
chi = c;
eng = e;
}
public int getSum(){
return (chi + eng);
}
}
public class test{
public static void main(String[] args){
student[] allStu = {new student("aStudent", 54, 77), new student("bStudent", 88, 27), new student("cStudent", 83, 77), new student("dStudent", 66, 44)};
System.out.println("Before Sorting Sum:");
for (int i = allStu.length - 1; i >= 0; i--){
System.out.println(allStu[i].name);}
/* 使用匿名類別物件
Arrays.sort(allStu, new Comparator<student>(){
public int compare(student aObj, student bObj){
int a, b, returnValue = 0;
a = aObj.getSum();
b = bObj.getSum();
if (a > b){
returnValue = 1;}
else if (a == b){
returnValue = 0;}
else if (a < b){
returnValue = -1;}
return returnValue;
}
});
*/
// 使用Lambda語法
Arrays.sort(allStu, (aObj, bObj) -> {
int a, b, returnValue = 0;
a = aObj.getSum();
b = bObj.getSum();
if (a > b){
returnValue = 1;}
else if (a == b){
returnValue = 0;}
else if (a < b){
returnValue = -1;}
return returnValue;
});
System.out.println("After Sorting Sum:");
for (int i = allStu.length - 1; i >= 0; i--){
System.out.println(allStu[i].name);}
}
}
package testPackage;
import java.util.*;
class student{
public String name;
private int chi;
private int eng;
public student(String n, int c, int e){
name = n;
chi = c;
eng = e;
}
public int getSum(){
return (chi + eng);
}
}
public class test{
public static void main(String[] args){
student[] allStu = {new student("aStudent", 54, 77), new student("bStudent", 88, 27), new student("cStudent", 83, 77), new student("dStudent", 66, 44)};
System.out.println("Before Sorting Sum:");
for (int i = allStu.length - 1; i >= 0; i--){
System.out.println(allStu[i].name);}
/* 使用匿名類別物件
Arrays.sort(allStu, new Comparator<student>(){
public int compare(student aObj, student bObj){
int a, b, returnValue = 0;
a = aObj.getSum();
b = bObj.getSum();
if (a > b){
returnValue = 1;}
else if (a == b){
returnValue = 0;}
else if (a < b){
returnValue = -1;}
return returnValue;
}
});
*/
// 使用Lambda語法
Arrays.sort(allStu, (aObj, bObj) -> {
int a, b, returnValue = 0;
a = aObj.getSum();
b = bObj.getSum();
if (a > b){
returnValue = 1;}
else if (a == b){
returnValue = 0;}
else if (a < b){
returnValue = -1;}
return returnValue;
});
System.out.println("After Sorting Sum:");
for (int i = allStu.length - 1; i >= 0; i--){
System.out.println(allStu[i].name);}
}
}
l 執行緒範例-使用匿名類別物件、Lambda語法:
package testPackage;
public class test{
public static void main(String[] args){
/* 使用匿名類別物件
Thread obj = new Thread(new Runnable(){
public void run(){
for (int i = 1; i <= 5; i++){
System.out.println("Hello World " + i);}
}
});
*/
// 使用Lambda語法
Thread obj = new Thread(() -> {
for (int i = 1; i <= 5; i++){
System.out.println("Hello World " + i);}
});
obj.start();
}
}
package testPackage;
public class test{
public static void main(String[] args){
/* 使用匿名類別物件
Thread obj = new Thread(new Runnable(){
public void run(){
for (int i = 1; i <= 5; i++){
System.out.println("Hello World " + i);}
}
});
*/
// 使用Lambda語法
Thread obj = new Thread(() -> {
for (int i = 1; i <= 5; i++){
System.out.println("Hello World " + i);}
});
obj.start();
}
}
Lambda語法與方法參考
l 範例:
package testPackage;
import java.util.Arrays;
public class test{
public static void main(String[] args){
String[] name = {"Red", "leaf", "Ethan", "lyra", "Brendan", "may"};
/* 使用Lambda語法
Arrays.sort(name, (str1, str2) -> str1.compareToIgnoreCase(str2));
*/
// 使用方法參考
Arrays.sort(name, String::compareToIgnoreCase);
for (int i = 0 ; i < name.length; i++){
System.out.println(name[i]);}
}
}
package testPackage;
import java.util.Arrays;
public class test{
public static void main(String[] args){
String[] name = {"Red", "leaf", "Ethan", "lyra", "Brendan", "may"};
/* 使用Lambda語法
Arrays.sort(name, (str1, str2) -> str1.compareToIgnoreCase(str2));
*/
// 使用方法參考
Arrays.sort(name, String::compareToIgnoreCase);
for (int i = 0 ; i < name.length; i++){
System.out.println(name[i]);}
}
}
沒有留言:
張貼留言