1.改變?nèi)諝v打印程序,讓每周從周日開(kāi)始箱残。同時(shí)讓它在結(jié)尾新打印一行(并且只新打印一行)。
01題參考答案:
package com.example;
import java.time.LocalDate;
public class LearnJava {
public static void main(String[] args) throws Exception {
System.out.println(" Mon Tue Wed Thu Fri Sat Sun");
final int month = 11;
LocalDate date = LocalDate.of(2017, month, 1);
final int dayOfWeek = date.getDayOfWeek().getValue();
for (int i=1; i<dayOfWeek; ++i) {
System.out.printf("%4c", ' ');
}
while (date.getMonthValue() == month) {
System.out.printf("%4d", date.getDayOfMonth());
if (date.getDayOfWeek().getValue() == 7) {
System.out.println();
}
date = date.plusDays(1);
}
final int continueValue = (8 - date.getDayOfWeek().getValue())%7 + 7;
for (int i=0; i<continueValue; ++i) {
System.out.printf("%4d", date.getDayOfMonth());
if (date.getDayOfWeek().getValue() == 7) {
System.out.println();
}
date = date.plusDays(1);
}
}
}
01題輸出效果:
2.思考一下 Scanner 類的 nextInt 方法。它是訪問(wèn)器方法還是修改器方法掸鹅?為什么?那 Random 類的 nextInt 方法呢拦赠?
02題參考答案(個(gè)人理解):
Scanner 類的 nextInt 方法是修改器方法巍沙,因?yàn)樗淖兞?Scanner 類的狀態(tài),使其讀取下一個(gè)輸入荷鼠。Random 類的 nextInt 方法是訪問(wèn)器方法句携,因?yàn)樗皇怯脕?lái)返回隨機(jī)整數(shù),而不會(huì)改變 Random 類的狀態(tài)允乐。
3.你曾經(jīng)寫(xiě)過(guò)返回值不為 void 的修改器方法嗎矮嫉?你曾有寫(xiě)過(guò)返回值為 void 的訪問(wèn)器方法嗎?可能的話給個(gè)例子牍疏。
03題參考答案:
package com.example;
import java.util.ArrayList;
public class LearnJava {
private static ArrayList<String> s_strings;
// 靜態(tài)初始化塊
static {
s_strings = new ArrayList<>();
s_strings.add("Mon");
s_strings.add("Tue");
s_strings.add("Wed");
s_strings.add("Thu");
s_strings.add("Fri");
}
// 返回值為 void 的訪問(wèn)器方法
public void printWeekdays() {
for (String string : s_strings) {
System.out.printf("%4s", string);
}
System.out.println();
}
// 返回值不為 void 的修改器方法
public boolean addSaturday() {
if (s_strings.size() >= 5) {
s_strings.add(5, "Sat");
return true;
}
return false;
}
// 返回值不為 void 的修改器方法
public boolean addSunday() {
if (s_strings.size() >= 6) {
s_strings.add(6, "Sun");
return true;
}
return false;
}
public static void main(String[] args) throws Exception {
LearnJava learnJava = new LearnJava();
learnJava.printWeekdays();
learnJava.addSaturday();
learnJava.printWeekdays();
learnJava.addSunday();
learnJava.printWeekdays();
}
}
03題輸出效果:
4.為什么不能實(shí)現(xiàn)一個(gè)可以交換兩個(gè) int 變量?jī)?nèi)容的 Java 方法蠢笋,但是卻可以編寫(xiě)一個(gè)交換兩個(gè) IntHolder 對(duì)象內(nèi)容的方法?(在 API 文檔中查詢這個(gè)比較晦澀的 IntHolder 類鳞陨。)你能交換連個(gè) Integer 對(duì)象的內(nèi)容嗎昨寞?
04題參考答案:
在 Java 中,所有參數(shù) —— 對(duì)象引用以及基本類型值 —— 都是值傳遞厦滤。因此援岩,不可能寫(xiě)出一個(gè)方法,將對(duì)象引用修改為其他東西掏导。我們可以查看以下的實(shí)現(xiàn)享怀,就能夠理解為何要借助 IntHolder 類來(lái)實(shí)現(xiàn)兩個(gè) Integer 變量值的交換了:
package com.example;
import org.omg.CORBA.IntHolder;
public class LearnJava {
private Integer s_integer_a = 1;
private Integer s_integer_b = 2;
public void printIntegerA_B() {
System.out.println(s_integer_a + " " + s_integer_b);
}
public void swapIntegerA_B() {
int temp = s_integer_a;
s_integer_a = s_integer_b;
s_integer_b = temp;
}
public void swapIntegerA_B(Integer a, Integer b) {
int temp = a;
a = b;
b = temp;
}
public void swapIntegerA_B(IntHolder a, IntHolder b) {
int temp = a.value;
a.value = b.value;
b.value = temp;
}
public static void main(String[] args) throws Exception {
LearnJava learnJava = new LearnJava();
learnJava.printIntegerA_B();
learnJava.swapIntegerA_B();
learnJava.printIntegerA_B();
Integer a = 3;
Integer b = 4;
System.out.println(a + " " + b);
learnJava.swapIntegerA_B(a, b);
System.out.println(a + " " + b);
IntHolder c = new IntHolder(5);
IntHolder d = new IntHolder(6);
System.out.println(c.value + " " + d.value);
learnJava.swapIntegerA_B(c, d);
System.out.println(c.value + " " + d.value);
}
}
04題輸出效果:
5.實(shí)現(xiàn)一個(gè)描述平面上點(diǎn)的不可能修改的 Point 類。提供一個(gè)設(shè)置具體點(diǎn)的構(gòu)造函數(shù)趟咆、一個(gè)設(shè)置為原點(diǎn)的無(wú)參數(shù)構(gòu)造函數(shù)添瓷,以及方法 getX梅屉、getY、translate 和 scale仰坦。translate 方法根據(jù)給定量在 x 和 y 方向上移動(dòng)該點(diǎn)履植。scale 方法根據(jù)給定因子在坐標(biāo)系按比例變化。實(shí)現(xiàn)這些方法以便它們將新的 Point 對(duì)象作為結(jié)果返回悄晃。例如:
Point p = new Point(3, 4).translate(1, 3).scale(0.5);
應(yīng)該設(shè)置 p 為坐標(biāo)系上為(2, 3.5)的點(diǎn)玫霎。
05題參考答案:
package com.example;
public class LearnJava {
public static class Point {
private double x;
private double y;
public Point(double x, double y) {
this.x = x;
this.y = y;
}
public Point() {
this(0, 0);
}
public double getX() {
return x;
}
public double getY() {
return y;
}
public Point translate(double x, double y) {
return new Point(this.x + x, this.y + y);
}
public Point scale(double s) {
return new Point(this.x * s, this.y * s);
}
}
public static void main(String[] args) {
Point p = new Point(3, 4).translate(1, 3).scale(0.5);
System.out.println("the point is: (" + p.getX() + "," + p.getY() + ")");
}
}
05題輸出效果:
6.重復(fù)前面的練習(xí)5,但是使得 translate 和 scale 方法變成修改器方法妈橄。
06題參考答案:
package com.example;
public class LearnJava {
public static class Point {
private double x;
private double y;
public Point(double x, double y) {
this.x = x;
this.y = y;
}
public Point() {
this(0, 0);
}
public double getX() {
return x;
}
public double getY() {
return y;
}
public Point translate(double x, double y) {
return new Point(this.x + x, this.y + y);
}
public Point scale(double s) {
return new Point(this.x * s, this.y * s);
}
public void setTranslate(double x, double y) {
this.x += x;
this.y += y;
}
public void setScale(double s) {
this.x *= s;
this.y *= s;
}
}
public static void main(String[] args) {
Point p = new Point(3, 4).translate(1, 3).scale(0.5);
System.out.println("the point is: (" + p.getX() + "," + p.getY() + ")");
p = new Point(3, 4);
p.setTranslate(1, 3);
p.setScale(0.5);
System.out.println("the point is: (" + p.getX() + "," + p.getY() + ")");
}
}
06題輸出效果:
7.給前面兩個(gè)版本的 Point 類添加 javadoc 注釋庶近。
07題參考答案:
package com.example;
public class LearnJava {
/**
* 一個(gè) <code>Point</code> 對(duì)象代表一個(gè)坐標(biāo)點(diǎn)
* 坐標(biāo)點(diǎn)中包含該坐標(biāo)對(duì)應(yīng)的橫坐標(biāo)的值 x 以及縱坐標(biāo)的值 y
* @author ZhaoDongshuang
* @version 1.0
*/
public static class Point {
private double x;
private double y;
/**
* 使用給定的 x 和 y 值構(gòu)造一個(gè)坐標(biāo)點(diǎn)對(duì)象
* @param x 橫坐標(biāo)的值
* @param y 縱坐標(biāo)的值
*/
public Point(double x, double y) {
this.x = x;
this.y = y;
}
/**
* 使用原點(diǎn)坐標(biāo)構(gòu)造一個(gè)坐標(biāo)點(diǎn)對(duì)象
*/
public Point() {
this(0, 0);
}
/**
* 獲取橫坐標(biāo)的值
* @return 返回 double 類型的橫坐標(biāo)的值
*/
public double getX() {
return x;
}
/**
* 獲取縱坐標(biāo)的值
* @return 返回 double 類型的縱坐標(biāo)的值
*/
public double getY() {
return y;
}
/**
* 獲取相對(duì)原坐標(biāo)點(diǎn)移動(dòng)之后的坐標(biāo)點(diǎn),該方法不改變?cè)凶鴺?biāo)點(diǎn)的狀態(tài)
* @param x 橫坐標(biāo)的移動(dòng)量
* @param y 縱坐標(biāo)的移動(dòng)量
* @return 返回移動(dòng)之后的坐標(biāo)點(diǎn)
*/
public Point translate(double x, double y) {
return new Point(this.x + x, this.y + y);
}
/**
* 獲取相對(duì)原坐標(biāo)點(diǎn)縮放之后的坐標(biāo)點(diǎn)眷蚓,該方法不改變?cè)凶鴺?biāo)點(diǎn)的狀態(tài)
* @param s 縮放因子
* @return 返回縮放之后的坐標(biāo)點(diǎn)
*/
public Point scale(double s) {
return new Point(this.x * s, this.y * s);
}
/**
* 將坐標(biāo)點(diǎn)按照給定的橫縱坐標(biāo)值進(jìn)行移動(dòng)
* @param x 橫坐標(biāo)的移動(dòng)量
* @param y 縱坐標(biāo)的移動(dòng)量
*/
public void setTranslate(double x, double y) {
this.x += x;
this.y += y;
}
/**
* 將坐標(biāo)點(diǎn)按照給定的縮放因子值進(jìn)行縮放
* @param s 縮放因子
*/
public void setScale(double s) {
this.x *= s;
this.y *= s;
}
}
public static void main(String[] args) {
Point p = new Point(3, 4).translate(1, 3).scale(0.5);
System.out.println("the point is: (" + p.getX() + "," + p.getY() + ")");
p = new Point(3, 4);
p.setTranslate(1, 3);
p.setScale(0.5);
System.out.println("the point is: (" + p.getX() + "," + p.getY() + ")");
}
}
8.在前面的練習(xí)中鼻种,提供的 Point 類的這些構(gòu)造函數(shù)和 getter 方法有些重復(fù)。大多數(shù) IDE 為編寫(xiě)樣板代碼都提供了快捷方式沙热。你的 IDE 都提供了哪些叉钥?
Android Studio 中在光標(biāo)選中構(gòu)造函數(shù),鍵盤快捷鍵 “alt+insert”篙贸,顯示構(gòu)造函數(shù)的快速構(gòu)建方法如下:
Android Studio 中在光標(biāo)選中某個(gè)變量投队,鍵盤快捷鍵 “alt+insert”,顯示變量的快速構(gòu)建方法如下:
9.實(shí)現(xiàn)一個(gè) Car 類爵川,模擬汽車沿著 x 軸移動(dòng)敷鸦,隨著移動(dòng)消耗燃油。提供一個(gè)按照給定英里數(shù)驅(qū)動(dòng)汽車的方法寝贡、給汽車燃料箱添加給定加侖(燃油)的方法扒披,以及獲取原點(diǎn)到油位的當(dāng)前距離的方法。在構(gòu)造函數(shù)中指定燃料效率(單位為每加侖多少英里)圃泡。Car 類應(yīng)該是不可修改類嗎碟案?為什么或者為什么不應(yīng)該?
09題參考答案:
package com.example;
import java.math.BigDecimal;
import java.math.RoundingMode;
public class LearnJava {
public static class Car {
private BigDecimal burningPower;
private BigDecimal oilVolume;
private BigDecimal miles;
public Car(BigDecimal burningPower, BigDecimal oilVolume, BigDecimal miles) {
this.burningPower = burningPower;
this.oilVolume = oilVolume;
this.miles = miles;
}
public Car(BigDecimal burningPower, BigDecimal oilVolume) {
this(burningPower, oilVolume, new BigDecimal(0));
}
public Car(BigDecimal burningPower) {
this(burningPower, new BigDecimal(0), new BigDecimal(0));
}
public void move(BigDecimal miles) {
if (oilVolume.compareTo(miles.divide(burningPower,
RoundingMode.UP)) == 1) {
this.miles = this.miles.add(miles);
} else {
this.miles = this.miles.add(oilVolume.multiply(burningPower));
}
}
public void addOil(BigDecimal oilVolume) {
this.oilVolume = this.oilVolume.add(oilVolume);
}
public BigDecimal getMiles() {
return miles;
}
}
public static void main(String[] args) {
// 使用下面第一種方式的 2.3 初始化 BigDecimal颇蜡,其值將變成 2.2999999999999998蟆淀,
// 所以建議使用第二種方式賦值
// method 1
// Car car = new Car(new BigDecimal(2.3), new BigDecimal(100));
// method 2
Car car = new Car(new BigDecimal("2.3"), new BigDecimal(100));
car.move(new BigDecimal(200));
System.out.println("Current move miles: " + car.getMiles().toString());
}
}
09題輸出效果:
雖然我們想要這臺(tái)車開(kāi)個(gè) 400 英里,但是在當(dāng)前的燃燒率和油量下澡匪,最多只能開(kāi)到 230 英里。
10.在 RandomNumbers 類中褒链,提供兩個(gè)靜態(tài)方法 randomElement唁情,從數(shù)組或者整數(shù)數(shù)組列表中獲得隨機(jī)元素。(如果數(shù)組或者數(shù)組列表為空甫匹,則返回 0甸鸟。)為什么不能使這兩個(gè)方法成為 int [] 或 ArrayList<Integer> 的實(shí)例方法惦费?
10題參考答案:
package com.example;
import java.util.ArrayList;
import java.util.Random;
public class LearnJava {
static class RandomNumbers {
private static Random s_random;
static {
s_random = new Random();
s_random.setSeed(System.currentTimeMillis());
}
public static Object randomElement(ArrayList<?> arrayList) {
if (arrayList.size() == 0) {
return 0;
}
return arrayList.get(Math.abs(s_random.nextInt())%(arrayList.size() - 1));
}
// public static Object randomElement(Integer[] arrayList) {
// return randomElement(new ArrayList<>(Arrays.asList(arrayList)));
// }
public static Object randomElement(int[] arrayList) {
ArrayList<Integer> intList = new ArrayList<>();
for (Integer i : arrayList) {
intList.add(i);
}
return randomElement(intList);
}
}
public static void main(String[] args) {
ArrayList<Integer> integers = new ArrayList<>();
for (int i=0; i<100; ++i) {
integers.add(i);
}
System.out.println(RandomNumbers.randomElement(integers).toString());
int[] arrays = new int[100];
for (int i=0; i<100; ++i) {
arrays[i] = i;
}
System.out.println(RandomNumbers.randomElement(arrays).toString());
}
}
10題輸出效果:
為什么不能使這兩個(gè)方法成為 int [] 或 ArrayList<Integer> 的實(shí)例方法?
這是因?yàn)樵?Java 中抢韭,基本類型不是類薪贫。無(wú)法創(chuàng)建其對(duì)象,即無(wú)法實(shí)現(xiàn)通過(guò)對(duì)象對(duì)方法的調(diào)用刻恭。
11.對(duì) System 和 LocalDate 類使用靜態(tài)導(dǎo)入瞧省,重寫(xiě) Cal 類。
11題參考答案:
package com.example;
import java.time.LocalDate;
import static java.time.LocalDate.of;
public class LearnJava {
public static void main(String[] args) throws Exception {
System.out.println(" Mon Tue Wed Thu Fri Sat Sun");
final int month = 11;
LocalDate date = of(2017, month, 1);
final int dayOfWeek = date.getDayOfWeek().getValue();
for (int i=1; i<dayOfWeek; ++i) {
System.out.printf("%4c", ' ');
}
while (date.getMonthValue() == month) {
System.out.printf("%4d", date.getDayOfMonth());
if (date.getDayOfWeek().getValue() == 7) {
System.out.println();
}
date = date.plusDays(1);
}
final int continueValue = (8 - date.getDayOfWeek().getValue())%7 + 7;
for (int i=0; i<continueValue; ++i) {
System.out.printf("%4d", date.getDayOfMonth());
if (date.getDayOfWeek().getValue() == 7) {
System.out.println();
}
date = date.plusDays(1);
}
}
}
11題輸出效果:
11題的示例中鳍贾,我只是使用了 of 這個(gè)靜態(tài)方法鞍匾,因此,就僅僅改動(dòng)了兩行代碼
import static java.time.LocalDate.of;
//...
LocalDate date = of(2017, month, 1);
12.創(chuàng)建一個(gè) HelloWorld.java 文件骑科,它在包 ch01.sec01 中聲明了 HelloWorld 類橡淑。把它放在某個(gè)目錄,但不在 ch01/sec01 子目錄咆爽。從存放文件的那個(gè)目錄運(yùn)行 javac HelloWorld.java梁棠。你會(huì)得到類文件嗎?類文件存放在哪里斗埂?接著運(yùn)行 java HelloWorld 會(huì)發(fā)生什么符糊?為什么?(提示:運(yùn)行 javap HelloWorld 并研究告警信息蜜笤。)最后濒蒋,為什么 javac -d . HelloWorld.java 更好?
12題參考答案:
會(huì)得到類文件把兔,文件存放在 HelloWorld.java 所在的目錄
運(yùn)行
java HelloWorld
會(huì)提示錯(cuò)誤:
錯(cuò)誤: 找不到或無(wú)法加載主類 HelloWorld
通過(guò)運(yùn)行
javap HelloWorld
我們可以知道這是因?yàn)椋?/p>
警告: 二進(jìn)制文件HelloWorld包含ch01.sec01.LearnJava
也就是無(wú)法正確的找到相應(yīng)的文件沪伙。
而使用
javac -d . HelloWorld.java
的好處是,class 文件會(huì)產(chǎn)生在單獨(dú)的目錄中县好,不會(huì)搞亂代碼樹(shù)围橡,并且 class 文件也有正確的子目錄結(jié)構(gòu)。
運(yùn)行完
javac -d . HelloWorld.java
再執(zhí)行
java ch01.sec01.LearnJava
就可以得到正常的輸出了缕贡。
13.從 http://opencsv.sourceforge.net 下載 OpenCSV 的 JAR 文件翁授。寫(xiě)個(gè)有 main 方法的類,讀取你選擇的 CSV 文件并打印部分內(nèi)容晾咪。OpenCSV 網(wǎng)站上有示例代碼收擦。我們還未學(xué)習(xí)處理異常。先用下面的內(nèi)容作為 main 方法頭:
public static void main(String[] args) throws Exception
這個(gè)練習(xí)的目的不是讓我們用 CSV 文件做些有用的事情谍倦,而是練習(xí)如何使用交付為 JAR 文件格式的類庫(kù)塞赂。
13題參考答案:
在 Android Studio 中,我們將下載的 jar 包昼蛀,放到 libs 目錄中:
在 Android Studio 中宴猾,選擇需要加入 JAR 包的 java module圆存,點(diǎn)擊鼠標(biāo)右鍵:
選擇 “Open Module Settings” 選項(xiàng):
點(diǎn)擊新彈出的窗口的右側(cè)的 “+” 符號(hào),選擇 “jar dependency” 選項(xiàng):
在彈出的窗口中選擇我們剛剛放到 libs 中的 JAR 包:
下面是測(cè)試代碼(其實(shí)不好用)仇哆,只是我們可以引用 JAR 包中的方法了沦辙。
package com.example;
import com.opencsv.CSVReader;
import java.io.FileReader;
import java.util.List;
public class LearnJava {
public static void main(String[] args) throws Exception {
CSVReader reader = new CSVReader(
new FileReader("/home/toby/SampleCSVFile_10600kb.csv"));
List<String[]> myEntries = reader.readAll();
}
}
14.編譯 Network 類。注意內(nèi)部類文件被命名為 Network$Member.class讹剔。使用 javap 程序檢查生成的代碼油讯。命令
javap -private Classname
顯示方法和實(shí)例變量。你在哪里看到外部類的引用辟拷?(在 Linux/Mac OS X 系統(tǒng)上撞羽,運(yùn)行 javap 時(shí),在 $ 符號(hào)前你需要輸入 “\”衫冻。)
14題參考答案:
我沒(méi)有編譯 Network 類诀紊,而是將第10題的例子編譯了一下:
package com.example;
import java.util.ArrayList;
import java.util.Random;
public class LearnJava {
static class RandomNumbers {
private static Random s_random;
static {
s_random = new Random();
s_random.setSeed(System.currentTimeMillis());
}
public static Object randomElement(ArrayList<?> arrayList) {
if (arrayList.size() == 0) {
return 0;
}
return arrayList.get(Math.abs(s_random.nextInt())%(arrayList.size() - 1));
}
// public static Object randomElement(Integer[] arrayList) {
// return randomElement(new ArrayList<>(Arrays.asList(arrayList)));
// }
public static Object randomElement(int[] arrayList) {
ArrayList<Integer> intList = new ArrayList<>();
for (Integer i : arrayList) {
intList.add(i);
}
return randomElement(intList);
}
}
public static void main(String[] args) {
ArrayList<Integer> integers = new ArrayList<>();
for (int i=0; i<100; ++i) {
integers.add(i);
}
System.out.println(RandomNumbers.randomElement(integers).toString());
int[] arrays = new int[100];
for (int i=0; i<100; ++i) {
arrays[i] = i;
}
System.out.println(RandomNumbers.randomElement(arrays).toString());
}
}
對(duì)上述代碼所在的類文件 LearnJava.java 運(yùn)行:
javac -d . LearnJava.java
之后14題測(cè)試的效果如下:
15.完整實(shí)現(xiàn) 2.6.1 節(jié)中的 Invoice 類。提供一個(gè)打印 invoice 的方法隅俘,以及構(gòu)造并打印示例 invoice 的演示程序邻奠。
15題參考答案:
package com.example;
import java.util.ArrayList;
public class LearnJava {
static class Invoice {
public static class Item {
String description;
int quantity;
double unitPrice;
public Item() {
this("", 0, 0);
}
public Item(String description, int quantity, double unitPrice) {
this.description = description;
this.quantity = quantity;
this.unitPrice = unitPrice;
}
double price() {
return quantity * unitPrice;
}
}
private ArrayList<Item> items = new ArrayList<>();
public void addItem(String description, int quantity, double unitPrice) {
Item newItem = new Item();
newItem.description = description;
newItem.quantity = quantity;
newItem.unitPrice = unitPrice;
items.add(newItem);
}
public void addItem(Item item) {
items.add(item);
}
public void printInvoice() {
for (Item item : items) {
System.out.print("description: " + item.description + ", ");
System.out.print("quantity: " + item.quantity + ", ");
System.out.println("unitPrice: " + item.unitPrice);
}
}
}
public static void main(String[] args) {
Invoice invoice = new Invoice();
invoice.addItem("Tomato", 12, 5);
Invoice.Item item0 = new Invoice.Item("Potato", 11, 6);
invoice.addItem(item0);
invoice.printInvoice();
}
}
15題輸出效果:
16.實(shí)現(xiàn)一個(gè) Queue 類 —— 一個(gè)無(wú)邊界的字符串隊(duì)列,分別提供在末尾添加字符串的 add 方法和從隊(duì)列頭部進(jìn)行刪除的 remove 方法为居。將元素存儲(chǔ)成鏈表節(jié)點(diǎn)碌宴。創(chuàng)建一個(gè)嵌套類 Node。Node 類應(yīng)該是靜態(tài)類或不應(yīng)該是靜態(tài)類嗎蒙畴?
16題參考答案:
靜態(tài)嵌套類沒(méi)有外部類的引用贰镣。當(dāng)嵌套類的實(shí)例不需要知道它屬于外部類的哪個(gè)實(shí)例時(shí),使用靜態(tài)嵌套類膳凝。只有當(dāng)這種信息重要時(shí)碑隆,才使用內(nèi)部類。
對(duì)于這個(gè)隊(duì)列來(lái)說(shuō)因?yàn)?Node 無(wú)需訪問(wèn) Queue 的成員或者方法蹬音,所以上煤,Node 可以是靜態(tài)的嵌套類。
package com.example;
import java.util.ArrayList;
public class LearnJava {
static class Queue {
private ArrayList<Node> nodes = new ArrayList<>();
public static class Node {
public String getContent() {
return content;
}
private String content;
public Node() {
this.content = "";
}
public Node(String content) {
this.content = content;
}
}
public int size() {
return nodes.size();
}
public void add(String value) {
Node node = new Node(value);
nodes.add(node);
}
public void remove() {
if (nodes.size() > 0) {
nodes.remove(0);
}
}
public void printValue(int i) {
if (i>=0 && i < nodes.size()) {
System.out.println(nodes.get(i).getContent());
} else {
System.out.println();
}
}
}
public static void main(String[] args) {
Queue queue = new Queue();
for (int i=0; i<50; ++i) {
queue.add(String.valueOf(i));
}
int i = 40;
while (i>0) {
queue.remove();
--i;
}
for (i=0; i<queue.size(); ++i) {
queue.printValue(i);
}
}
}
16題輸出效果:
17.提供一個(gè) iterator —— 依次產(chǎn)生隊(duì)列元素的對(duì)象 —— 就是上一道練習(xí)題中的隊(duì)列著淆。將 Interator 作為擁有 next 和 hasNext 方法的嵌套類劫狠。給 Queue 類提供 iterator() 方法,該方法產(chǎn)生 Queue.Iterator永部。Iterator 應(yīng)該是靜態(tài)類或不應(yīng)該是靜態(tài)類嗎独泞?
17題參考答案:
Iterator 不應(yīng)該是靜態(tài)嵌套類,因?yàn)樗枰L問(wèn)外部類的非靜態(tài)成員苔埋。
package com.example;
import java.util.ArrayList;
public class LearnJava {
static class Queue {
private ArrayList<Node> nodes = new ArrayList<>();
public static class Node {
public String getContent() {
return content;
}
private String content;
public Node() {
this.content = "";
}
public Node(String content) {
this.content = content;
}
}
public class Iterator {
private int i = -1;
public Iterator() {
i = -1;
}
public Iterator(int i) {
this.i = i;
}
public Node next() {
return nodes.get(++i);
}
public boolean hasNext() {
return (i+1) < nodes.size();
}
}
public int size() {
return nodes.size();
}
public void add(String value) {
Node node = new Node(value);
nodes.add(node);
}
public void remove() {
if (nodes.size() > 0) {
nodes.remove(0);
}
}
public void printValue(int i) {
if (i>=0 && i < nodes.size()) {
System.out.println(nodes.get(i).getContent());
} else {
System.out.println();
}
}
public Iterator iterator() {
return new Iterator(-1);
}
}
public static void main(String[] args) {
Queue queue = new Queue();
for (int i=0; i<50; ++i) {
queue.add(String.valueOf(i));
}
int i = 40;
while (i>0) {
queue.remove();
--i;
}
Queue.Iterator iterator = queue.iterator();
while (iterator.hasNext()) {
Queue.Node node = iterator.next();
System.out.println(node.getContent());
}
}
}
17題輸出效果: