201871010131-張興盼《面向對象程序設計(java)》第八周學習總結


 

項目

內容

這個作業屬於哪個課程

https://www.cnblogs.com/nwnu-daizh/

這個作業的要求在哪里

https://www.cnblogs.com/nwnu-daizh/p/11703678.html

作業學習目標

(1) 掌握接口定義方法;

(2) 掌握實現接口類的定義要求;

(3) 掌握實現了接口類的使用要求;

(4) 掌握程序回調設計模式;

(5) 掌握Comparator接口用法;

(6) 掌握對象淺層拷貝與深層拷貝方法;

(7) 掌握Lambda表達式語法;

(8) 了解內部類的用途及語法要求。

 

第一部分:總結第六章理論知識

6.1.1接口

1.Java為了克服單繼承的缺點,Java使用了接口,一個類可以實現一個或多個接口。

2. Java程序設計語言中,接口不是類,而是對類的一組需求描述,由常量和一組抽象方法組成。

3. 接口中不包括變量和有具體實現的方法。

4.只要類實現了接口,則該類要遵從接口描述的統一格式進行定義,並且可以在任何需要該接口的地方使用這個類的對象.

5.聲明方式: public interface 接口名 { …… }   接口體中包含常量定義和方法定義,接口中只進行方法的聲明,不提供方法的實現。

6.類似建立類的繼承關系,接口也可以擴展。 接口的擴展技術使得從具有較高通用性的接口存在多條鏈延伸到具有較高專用性的接口。

7.在類聲明時用implements關鍵字聲明使用一個或多個接口

  class Employee implements Printable { …… } 

  一個類使用了某個接口,那么這個類必須實現該接口的所有方法,即為這些方法提供方法體。

    一個類可以實現多個接口,接口間應該用逗號分隔開。

     class Employee implements Cloneable,Comparable

8.接口不能構造接口對象,但可以聲明接口變量以指向一個實現了該接口的類對象。

  Comparablex = new Comparable(…);       //ERROR

  Comparable  x= new Employee(…);     //OK

9.可以用instanceof檢查對象是否實現了某個接口。

  if  (anObject instanceof Comparable) {   ……} 

6.1.2  接口與抽象類

1.抽象類:用abstract來聲明,沒有具體實例對象的類,不能用new來創建對象。可包含常規類所包含的任何東西。抽象類必須由子類繼承,如果abstract類的子類不是抽象類,那么子類必須重寫父類中所有的abstract方法。

2.接口:用interfaces聲明,是抽象方法和常量值定義的集合。從本質上講,接口是一個特殊的抽象類,這種抽象類中只包常量和方法的定義,而沒有變量和方法的定義。接口中只能定義抽象方法,而且這些方法默認為public的。只有類實現了接口,就可以在任何需要該接口的地方使用這個類的對象。此外,一個類可以實現多個接口。

接口與抽象類的區別:

 A.接口不能實現任何方法,而抽象類可以。

 B.類可以實現許多接口,但只有一個父類。

 C.接口不是類分級結構的一部分,無任何聯系的類可以實現相同的接口。

6.2.1 接口實例

1.回調(callback):一種程序設計模式,在這種模式中,可指出某個特定事件發生時程序應該采取的動作。 在java.swing包中有一個Timer類,可以使用它在到達給定的時間間隔時觸發一個事件。

2Compare接口

 a)所在包:java.util.*

 b)Comparator接口定義

    public interface Comparator<T>{

    int  compare(T o1,T o2);

        ......

      }

   c)用途一:處理字符串按長度進行排序操作

3. Object類的Clone方法
 a)當拷貝一個對象變量時,原始變量與拷貝變量引用同一個對象。這樣,改變一個變量所引用的對象會對另一個變量產生影響。

b)如果要創建一個對象新的copy,它的最初狀態與 original一樣,但以后可以各自改變狀態,就需要使用Object類的clone方法。

c)Object類的clone()方法是一個native方法。

dObject類中的clone()方法被protected()修飾符修飾。這意味着在用戶編寫的代碼中不能直接調用它。如果要直接應用clone()方法,就需覆蓋clone()方法,並要把clone()方法的屬性設置為public

 eObject.clone()方法返回一個Object對象。必須進行強制類型轉換才能得到所需要的類型。

 

4.淺層拷貝:被拷貝對象的所有常量成員和基本類型屬性都有與原來對象相同的拷貝值,而若成員域是一個對象,則被拷貝對象該對象域的對象引用仍然指向原來的對象。

5.深層拷貝:被拷貝對象的所有成員域都含有與原 來對象相同的值,且對象域將指向被復制過的新對 象,而不是原有對象被引用的對象。換言之,深層拷貝將拷貝對象內引用的對象也拷貝一遍。

6.2.2   Java中對象克隆的實現

1.在子類中實現Cloneable接口

2.為了獲得對象的一份拷貝,可以利用Object類的clone方法。

3.在子類中覆蓋超類的clone方法,聲明為public

4.在子類的clone方法中,調用super.clone()

6.3 Lambda表達式

1.Java Lambda表達式是Java 8引入的一個新的功能,主要用途是提供一個函數化的語法來簡化編碼。

2.Lambda表達式本質上是一個匿名方法。

  public intadd(intx, inty) {

      return x + y; }

       轉成Lambda表達式后是:

       (intx, inty) -> x + y; 

3.Lambda表達式的語法基本結構

      (arguments)->body

 有如下幾種情況:

  a)參數類型可推導時,不需要指定類型,   (a)->System.out.println(a)

  b)只有一個參數且類型可推導時,不強制寫(),     a->System.out.println(a)

  c)參數指定類型時,必須有括號,如(int a)->System.out.println(a)

  d)參數可以為空,如()->System.out.println("hello")

  e)body需要用{}包含語句,當只有一條語句時{}可省略

4)函數式接口Functionallnterface

   a)Java Lambda表達式以函數式接口為應用基礎

   b)函數式接口(Functionallnterface

       只有一個方法的接口,這類接口的目的是為了一個單一的操作。常見的接口如:ActionListener,Runnable,Comparator都是函數式接口,並且都

         標注了注解@Functionallnterface.

   c)函數式接口用作表示lambda表達式的類型。

6.4.1   內部類

1)內部類(inner class)是定義在一個類內部的類。

2)外層的類成為外部類(outer class).

3)內部類主要用於事件處理。 使用內部類的原因有以下三個:

   a)內部類方法可以訪問該類定義所在的作用域中的數據,包括私有數據。

   b)內部類能夠隱藏起來,不為同一包中的其他類所見。

   c)想要定義一個回調函數且不想編寫大量代碼時, 使用匿名內部類比較便捷。

4)內部類的聲明

   內部類的聲明格式如下:

     [修飾符] class outerClass{

            ...

            [修飾符]class  innerClass{

                    ...

            }

           ...

    }

5)內部類可以直接訪問外部類的成員,包括private成員,但是內部類的成員卻不能被外部類直接訪問。內部類中加上修飾符訪問外部類中的同名域。

6.4.2局部內部類

1)內部類並非只能在類內定義,也可以在程序塊內定義局部內部類。例如,在方法中,甚至在for循環體內部。

2)局部內部類不能用publicprivate訪問修飾符進行聲明,它的作用域被限定在聲明這個局部類的塊中。

3)局部內部類可以訪問方法中的final類型的局部變量。

6.4.3 匿名內部類

1)若只創建類的一個對象,則不該為該類命名,這種類稱為匿名內部類。

2)由於匿名類沒有類名,所以匿名類不能有構造器,取而代之的是將構造器參數傳遞給超類的構造器。

3)若匿名內部類實現接口時,則匿名內部類不能有任何構造參數。

4)如果構造參數的閉圓括號跟一個開花括號,表明正在定義的就是匿名內部類。

6.4.4 靜態內部類

1)如果用static修飾一個內部類,這個類就相當於是一個外部定義的類,所以static的內部類中可以聲明static成員,但非static的內部類中的成員不能聲明為static的。

     static的內部類不能再使用外部類的非static的成員變量。

2static內部類很少使用。

 

第二部分:實驗部分

實驗1 導入第6章示例程序,測試程序並進行代碼注釋。

 

測試程序1編輯、編譯、調試運行閱讀教材214-215頁程序6-16-2,理解程序並分析程序運行結果;

在程序中相關代碼處添加新知識的注釋。

掌握接口的實現用法;

掌握內置接口Compareable的用法。

6-1代碼如下:

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

package interfaces;

 

import java.util.*;

 

/**

 * This program demonstrates the use of the Comparable interface.

 * @version 1.30 2004-02-27

 * @author Cay Horstmann

 */

public class EmployeeSortTest    //EmployeeSortTest關聯Employee;

{

   public static void main(String[] args)

   {

      var staff = new Employee[3];  //局部對象數組;

 

      staff[0] = new Employee("Harry Hacker", 35000);

      staff[1] = new Employee("Carl Cracker", 75000);

      staff[2] = new Employee("Tony Tester", 38000);

 

      Arrays.sort(staff);      //進行排序;

 

      // print out information about all Employee objects

      for (Employee e : staff)

         System.out.println("name=" + e.getName() + ",salary=" + e.getSalary());

   }

}

 運行結果如下:

 

 

 

項目

內容

這個作業屬於哪個課程

https://www.cnblogs.com/nwnu-daizh/

這個作業的要求在哪里

https://www.cnblogs.com/nwnu-daizh/p/11703678.html

作業學習目標

(1) 掌握接口定義方法;

(2) 掌握實現接口類的定義要求;

(3) 掌握實現了接口類的使用要求;

(4) 掌握程序回調設計模式;

(5) 掌握Comparator接口用法;

(6) 掌握對象淺層拷貝與深層拷貝方法;

(7) 掌握Lambda表達式語法;

(8) 了解內部類的用途及語法要求。

 

 

 

第一部分:總結第六章理論知識

 

6.1.1接口

 

1.Java為了克服單繼承的缺點,Java使用了接口,一個類可以實現一個或多個接口。

 

2. Java程序設計語言中,接口不是類,而是對類的一組需求描述,由常量和一組抽象方法組成。

 

3. 接口中不包括變量和有具體實現的方法。

 

4.只要類實現了接口,則該類要遵從接口描述的統一格式進行定義,並且可以在任何需要該接口的地方使用這個類的對象.

 

5.聲明方式: public interface 接口名 { …… }   接口體中包含常量定義和方法定義,接口中只進行方法的聲明,不提供方法的實現。

 

6.類似建立類的繼承關系,接口也可以擴展。 接口的擴展技術使得從具有較高通用性的接口存在多條鏈延伸到具有較高專用性的接口。

 

7.在類聲明時用implements關鍵字聲明使用一個或多個接口

 

  class Employee implements Printable { …… } 

 

  一個類使用了某個接口,那么這個類必須實現該接口的所有方法,即為這些方法提供方法體。

 

    一個類可以實現多個接口,接口間應該用逗號分隔開。

 

     class Employee implements Cloneable,Comparable

 

8.接口不能構造接口對象,但可以聲明接口變量以指向一個實現了該接口的類對象。

 

  Comparablex = new Comparable(…);       //ERROR

 

  Comparable  x= new Employee(…);     //OK

 

9.可以用instanceof檢查對象是否實現了某個接口。

 

  if  (anObject instanceof Comparable) {   ……} 

 

6.1.2  接口與抽象類

 

1.抽象類:用abstract來聲明,沒有具體實例對象的類,不能用new來創建對象。可包含常規類所包含的任何東西。抽象類必須由子類繼承,如果abstract類的子類不是抽象類,那么子類必須重寫父類中所有的abstract方法。

 

2.接口:用interfaces聲明,是抽象方法和常量值定義的集合。從本質上講,接口是一個特殊的抽象類,這種抽象類中只包常量和方法的定義,而沒有變量和方法的定義。接口中只能定義抽象方法,而且這些方法默認為public的。只有類實現了接口,就可以在任何需要該接口的地方使用這個類的對象。此外,一個類可以實現多個接口。

 

接口與抽象類的區別:

 

 A.接口不能實現任何方法,而抽象類可以。

 

 B.類可以實現許多接口,但只有一個父類。

 

 C.接口不是類分級結構的一部分,無任何聯系的類可以實現相同的接口。

 

6.2.1 接口實例

 

1.回調(callback):一種程序設計模式,在這種模式中,可指出某個特定事件發生時程序應該采取的動作。 在java.swing包中有一個Timer類,可以使用它在到達給定的時間間隔時觸發一個事件。

 

2Compare接口

 

 a)所在包:java.util.*

 

 b)Comparator接口定義

 

    public interface Comparator<T>{

 

    int  compare(T o1,T o2);

 

        ......

 

      }

 

   c)用途一:處理字符串按長度進行排序操作

 

3. Object類的Clone方法
 a)當拷貝一個對象變量時,原始變量與拷貝變量引用同一個對象。這樣,改變一個變量所引用的對象會對另一個變量產生影響。

 

b)如果要創建一個對象新的copy,它的最初狀態與 original一樣,但以后可以各自改變狀態,就需要使用Object類的clone方法。

 

c)Object類的clone()方法是一個native方法。

 

dObject類中的clone()方法被protected()修飾符修飾。這意味着在用戶編寫的代碼中不能直接調用它。如果要直接應用clone()方法,就需覆蓋clone()方法,並要把clone()方法的屬性設置為public

 

 eObject.clone()方法返回一個Object對象。必須進行強制類型轉換才能得到所需要的類型。

 

 

 

4.淺層拷貝:被拷貝對象的所有常量成員和基本類型屬性都有與原來對象相同的拷貝值,而若成員域是一個對象,則被拷貝對象該對象域的對象引用仍然指向原來的對象。

 

5.深層拷貝:被拷貝對象的所有成員域都含有與原 來對象相同的值,且對象域將指向被復制過的新對 象,而不是原有對象被引用的對象。換言之,深層拷貝將拷貝對象內引用的對象也拷貝一遍。

 

6.2.2   Java中對象克隆的實現

 

1.在子類中實現Cloneable接口

 

2.為了獲得對象的一份拷貝,可以利用Object類的clone方法。

 

3.在子類中覆蓋超類的clone方法,聲明為public

 

4.在子類的clone方法中,調用super.clone()

 

6.3 Lambda表達式

 

1.Java Lambda表達式是Java 8引入的一個新的功能,主要用途是提供一個函數化的語法來簡化編碼。

 

2.Lambda表達式本質上是一個匿名方法。

 

  public intadd(intx, inty) {

 

      return x + y; }

 

       轉成Lambda表達式后是:

 

       (intx, inty) -> x + y; 

 

3.Lambda表達式的語法基本結構

 

      (arguments)->body

 

 有如下幾種情況:

 

  a)參數類型可推導時,不需要指定類型,   (a)->System.out.println(a)

 

  b)只有一個參數且類型可推導時,不強制寫(),     a->System.out.println(a)

 

  c)參數指定類型時,必須有括號,如(int a)->System.out.println(a)

 

  d)參數可以為空,如()->System.out.println("hello")

 

  e)body需要用{}包含語句,當只有一條語句時{}可省略

 

4)函數式接口Functionallnterface

 

   a)Java Lambda表達式以函數式接口為應用基礎

 

   b)函數式接口(Functionallnterface

 

       只有一個方法的接口,這類接口的目的是為了一個單一的操作。常見的接口如:ActionListener,Runnable,Comparator都是函數式接口,並且都

 

         標注了注解@Functionallnterface.

 

   c)函數式接口用作表示lambda表達式的類型。

 

6.4.1   內部類

 

1)內部類(inner class)是定義在一個類內部的類。

 

2)外層的類成為外部類(outer class).

 

3)內部類主要用於事件處理。 使用內部類的原因有以下三個:

 

   a)內部類方法可以訪問該類定義所在的作用域中的數據,包括私有數據。

 

   b)內部類能夠隱藏起來,不為同一包中的其他類所見。

 

   c)想要定義一個回調函數且不想編寫大量代碼時, 使用匿名內部類比較便捷。

 

4)內部類的聲明

 

   內部類的聲明格式如下:

 

     [修飾符] class outerClass{

 

            ...

 

            [修飾符]class  innerClass{

 

                    ...

 

            }

 

           ...

 

    }

 

5)內部類可以直接訪問外部類的成員,包括private成員,但是內部類的成員卻不能被外部類直接訪問。內部類中加上修飾符訪問外部類中的同名域。

 

6.4.2局部內部類

 

1)內部類並非只能在類內定義,也可以在程序塊內定義局部內部類。例如,在方法中,甚至在for循環體內部。

 

2)局部內部類不能用publicprivate訪問修飾符進行聲明,它的作用域被限定在聲明這個局部類的塊中。

 

3)局部內部類可以訪問方法中的final類型的局部變量。

 

6.4.3 匿名內部類

 

1)若只創建類的一個對象,則不該為該類命名,這種類稱為匿名內部類。

 

2)由於匿名類沒有類名,所以匿名類不能有構造器,取而代之的是將構造器參數傳遞給超類的構造器。

 

3)若匿名內部類實現接口時,則匿名內部類不能有任何構造參數。

 

4)如果構造參數的閉圓括號跟一個開花括號,表明正在定義的就是匿名內部類。

 

6.4.4 靜態內部類

 

1)如果用static修飾一個內部類,這個類就相當於是一個外部定義的類,所以static的內部類中可以聲明static成員,但非static的內部類中的成員不能聲明為static的。

 

     static的內部類不能再使用外部類的非static的成員變量。

 

2static內部類很少使用。

 

 

 

第二部分:實驗部分

 

實驗1 導入第6章示例程序,測試程序並進行代碼注釋。

 

 

 

測試程序1編輯、編譯、調試運行閱讀教材214-215頁程序6-16-2,理解程序並分析程序運行結果;

 

在程序中相關代碼處添加新知識的注釋。

 

掌握接口的實現用法;

 

掌握內置接口Compareable的用法。

 

6-1代碼如下:

 

 

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

package interfaces;

 

import java.util.*;

 

/**

 * This program demonstrates the use of the Comparable interface.

 * @version 1.30 2004-02-27

 * @author Cay Horstmann

 */

public class EmployeeSortTest    //EmployeeSortTest關聯Employee;

{

   public static void main(String[] args)

   {

      var staff = new Employee[3];  //局部對象數組;

 

      staff[0] = new Employee("Harry Hacker", 35000);

      staff[1] = new Employee("Carl Cracker", 75000);

      staff[2] = new Employee("Tony Tester", 38000);

 

      Arrays.sort(staff);      //進行排序;

 

      // print out information about all Employee objects

      for (Employee e : staff)

         System.out.println("name=" + e.getName() + ",salary=" + e.getSalary());

   }

}

 

 運行結果如下:

 

 

 

6-2代碼如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

package interfaces;

 

public class Employee implements Comparable<Employee>//Employee實現JDK內置接口Comparable

{

   private String name;

   private double salary;

   //構造方法

   public Employee(String name, double salary)

   {

      this.name = name;

      this.salary = salary;

   }

   //訪問器

   public String getName()

   {

      return name;

   }

 

   public double getSalary()

   {

      return salary;

   }

   //調用方法

   public void raiseSalary(double byPercent)

   {

      double raise = salary * byPercent / 100;

      salary += raise;

   }

 

   /**

    * Compares employees by salary

    * @param other another Employee object

    * @return a negative value if this employee has a lower salary than

    * otherObject, 0 if the salaries are the same, a positive value otherwise

    */

   public int compareTo(Employee other)

   {

      return Double.compare(salary, other.salary);//靜態Double.compare方法

   }

}

  

運行結果如下

 

 

 

測試程序二:編輯、編譯、調試以下程序,結合程序運行結果理解程序;

代碼如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

package test;

interface  A

{

  double g=9.8;

  void show( );

}

class C implements A

{

  public void show( )

  {System.out.println("g="+g);}

}

 

public class InterfaceTest

{

  public static void main(String[ ] args)

  {

       A a=new C( );

       a.show( );

       System.out.println("g="+C.g);

  }

}

運行結果如下

 

 

 

測試程序三:

elipse IDE中調試運行教材2236-3,結合程序運行結果理解程序;

26行、36行代碼參閱224頁,詳細內容涉及教材12章。

在程序中相關代碼處添加新知識的注釋。

掌握回調程序設計模式;

 

6-3代碼如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

package timer;

 

/**

   @version 1.02 2017-12-14

   @author Cay Horstmann

*/

 

import java.awt.*;

import java.awt.event.*;

import java.time.*;

import javax.swing.*;

 

public class TimerTest

   public static void main(String[] args)

   { 

      var listener = new TimePrinter();  //創建類對象;

 

      // construct a timer that calls the listener

      // once every second        //時間間隔為10秒;

      var timer = new Timer(1000, listener);   //創建Timer類對象;

      timer.start();

 

      // keep program running until the user selects "OK"   //顯示一個包含一條消息和OK按鈕的對話框;

      JOptionPane.showMessageDialog(null, "Quit program?"); //parent為null時對話框顯示在屏幕的中央;

      System.exit(0);

   }

}

 

class TimePrinter implements ActionListener  //接口定義在implement包中;

{   

   public void actionPerformed(ActionEvent event)//入口參數為ActionEvent event;

   { 

      System.out.println("At the tone, the time is "

         + Instant.ofEpochMilli(event.getWhen()));

      Toolkit.getDefaultToolkit().beep();    //工具箱包含有關GUI環境的信息;

   }

}

運行結果如下:

 

 

測試程序4

調試運行教材229-231頁程序6-46-5,結合程序運行結果理解程序;

在程序中相關代碼處添加新知識的注釋.

掌握對象克隆實現技術;

掌握淺拷貝和深拷貝的差別。

 

6-4代碼如下

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

package clone;

 

/**

 * This program demonstrates cloning.

 * @version 1.11 2018-03-16

 * @author Cay Horstmann

 */

public class CloneTest

{

   public static void main(String[] args) throws CloneNotSupportedException

   {

      var original = new Employee("John Q. Public", 50000);

      original.setHireDay(2000, 1, 1);

      Employee copy = original.clone();  //新對象copy初始狀態與original相同,之后會有各自不同的狀態;

      copy.raiseSalary(10);

      copy.setHireDay(2002, 12, 31);

      System.out.println("original=" + original);

      System.out.println("copy=" + copy);

   }

}

運行結果如下:

 

 

6-5代碼如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

package clone;

 

import java.util.Date;

import java.util.GregorianCalendar;

 

public class Employee implements Cloneable

{

   private String name;

   private double salary;

   private Date hireDay;

 

   public Employee(String name, double salary)

   {

      this.name = name;

      this.salary = salary;

      hireDay = new Date();

   }

 

   public Employee clone() throws CloneNotSupportedException //重新定義clone為public,創建深拷貝的clone的方法;

   {

      // call Object.clone()   // 創建深拷貝的clone方法;

      Employee cloned = (Employee) super.clone();

 

      // clone mutable fields    //克隆可變的字段,

      cloned.hireDay = (Date) hireDay.clone();

 

      return cloned;

   }

 

   /**

    * Set the hire day to a given date.

    * @param year the year of the hire day

    * @param month the month of the hire day

    * @param day the day of the hire day

    */

   public void setHireDay(int year, int month, int day)

   {

      Date newHireDay = new GregorianCalendar(year, month - 1, day).getTime();

       

      // example of instance field mutation  實例字段突變的例子;

      hireDay.setTime(newHireDay.getTime());

   }

 

   public void raiseSalary(double byPercent)

   {

      double raise = salary * byPercent / 100;

      salary += raise;

   }

 

   public String toString()

   {

      return "Employee[name=" + name + ",salary=" + salary + ",hireDay=" + hireDay + "]";

   }

}

運行結果如下:

 

 

實驗2: 導入第6章示例程序6-6,學習Lambda表達式用法。

調試運行教材233-234頁程序6-6,結合程序運行結果理解程序;

在程序中相關代碼處添加新知識的注釋。

27-29行代碼與教材223頁程序對比,將27-29行代碼與此程序對比,體會Lambda表達式的優點。

 

6-6代碼如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

package lambda;

 

import java.util.*;

 

import javax.swing.*;

import javax.swing.Timer;

 

/**

 * This program demonstrates the use of lambda expressions.

 * @version 1.0 2015-05-12

 * @author Cay Horstmann

 */

public class LambdaTest

{

   public static void main(String[] args)

   {

      var planets = new String[] { "Mercury", "Venus", "Earth", "Mars",

         "Jupiter", "Saturn", "Uranus", "Neptune" };  //定義數組plants;

      System.out.println(Arrays.toString(planets));

      System.out.println("Sorted in dictionary order:");

      Arrays.sort(planets);//Arrays.sort方法接受Lambda類的對象;

      System.out.println(Arrays.toString(planets));

      System.out.println("Sorted by length:");

      Arrays.sort(planets, (first, second) -> first.length() - second.length());//檢查一個字符串是否比另一個短;

      System.out.println(Arrays.toString(planets));//提供lanbda表達式在底層,Arrays.sort方法會接收實現Comparator<string>某各類的對象;

             

      var timer = new Timer(1000, event ->

         System.out.println("The time is " + new Date()));//用已有的方法完成要傳遞到其他代碼的某個動作;

      timer.start();  

          

      // keep program running until user selects "OK"

      JOptionPane.showMessageDialog(null, "Quit program?");   //保持程序運行,直到用戶選擇“OK"

      System.exit(0);        

   }

}

運行結果如下 

 

 

實驗3: 編程練習

編制一個程序,將身份證號.txt 中的信息讀入到內存中;

按姓名字典序輸出人員信息;

查詢最大年齡的人員信息;

查詢最小年齡人員信息;

輸入你的年齡,查詢身份證號.txt中年齡與你最近人的姓名、身份證號、年齡、性別和出生地;

查詢人員中是否有你的同鄉。

實驗代碼如下:

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

package ID;

 

import java.io.BufferedReader;

import java.io.File;

import java.io.FileInputStream;

import java.io.FileNotFoundException;

import java.io.IOException;

import java.io.InputStreamReader;

import java.util.ArrayList;

import java.util.Arrays;

import java.util.Scanner;

import java.util.Collections;//對集合進行排序、查找、修改等;

 

public class Main {

    private static ArrayList<Citizen> citizenlist;

 

    public static void main(String[] args) {

        citizenlist = new ArrayList<>();

        Scanner scanner = new Scanner(System.in);

        File file = new File("D:/java/身份證號.txt");

        //異常捕獲

        try {

            FileInputStream fis = new FileInputStream(file);

            BufferedReader in = new BufferedReader(new InputStreamReader(fis));

            String temp = null;

            while ((temp = in.readLine()) != null) {

 

                Scanner linescanner = new Scanner(temp);

 

                linescanner.useDelimiter(" ");

                String name = linescanner.next();

                String id = linescanner.next();

                String sex = linescanner.next();

                String age = linescanner.next();

                String birthplace = linescanner.nextLine();

                Citizen citizen = new Citizen();

                citizen.setName(name);

                citizen.setId(id);

                citizen.setSex(sex);

                // 將字符串轉換成10進制數

                int ag = Integer.parseInt(age);

                citizen.setage(ag);

                citizen.setBirthplace(birthplace);

                citizenlist.add(citizen);

 

            }

        } catch (FileNotFoundException e) {

            System.out.println("信息文件找不到");

            e.printStackTrace();

        } catch (IOException e) {

            System.out.println("信息文件讀取錯誤");

            e.printStackTrace();

        }

        boolean isTrue = true;

        while (isTrue) {

 

            System.out.println("1.按姓名字典序輸出人員信息");

            System.out.println("2.查詢最大年齡的人員信息、查詢最小年齡人員信息");

            System.out.println("3.查詢人員中是否有你的同鄉");

            System.out.println("4.輸入你的年齡,查詢文件中年齡與你最近人的姓名、身份證號、年齡、性別和出生地");

            System.out.println("5.退出");

            int nextInt = scanner.nextInt();

            switch (nextInt) {

            case 1:

                Collections.sort(citizenlist);

                System.out.println(citizenlist.toString());

                break;

            case 2:

                int max = 0, min = 100;

                int m, k1 = 0, k2 = 0;

                for (int i = 1; i < citizenlist.size(); i++) {

                    m = citizenlist.get(i).getage();

                    if (m > max) {

                        max = m;

                        k1 = i;

                    }

                    if (m < min) {

                        min = m;

                        k2 = i;

                    }

                }

                System.out.println("年齡最大:" + citizenlist.get(k1));

                System.out.println("年齡最小:" + citizenlist.get(k2));

                break;

            case 3:

                System.out.println("出生地:");

                String find = scanner.next();

                String place = find.substring(0, 3);

                for (int i = 0; i < citizenlist.size(); i++) {

                    if (citizenlist.get(i).getBirthplace().substring(1, 4).equals(place))

                        System.out.println("出生地" + citizenlist.get(i));

                }

                break;

            case 4:

                System.out.println("年齡:");

                int yourage = scanner.nextInt();

                int near = peer(yourage);

                int j = yourage - citizenlist.get(near).getage();

                System.out.println("" + citizenlist.get(near));

                break;

            case 5:

                isTrue = false;

                System.out.println("程序已退出!");

                break;

            default:

                System.out.println("輸入有誤");

            }

        }

    }

 

    public static int peer(int age) {

        int flag = 0;

        int min = 53, j = 0;

        for (int i = 0; i < citizenlist.size(); i++) {

            j = citizenlist.get(i).getage() - age;

            if (j < 0)

                j = -j;

            if (j < min) {

                min = j;

                flag = i;

            }

        }

        return flag;

    }

}

 

  

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

package ID;

public class Citizen implements Comparable<Citizen> {

 

    private String name;

    private String id;

    private String sex;

    private int age;

    private String birthplace;

 

    public String getName() {

        return name;

    }

 

    public void setName(String name) {

        this.name = name;

    }

 

    public String getId() {

        return id;

    }

 

    public void setId(String id) {

        this.id = id;

    }

 

    public String getSex() {

        return sex;

    }

 

    public void setSex(String sex) {

        this.sex = sex;

    }

 

    public int getage() {

        return age;

    }

 

    public void setage(int age) {

        this.age = age;

    }

 

    public String getBirthplace() {

        return birthplace;

    }

 

    public void setBirthplace(String birthplace) {

        this.birthplace = birthplace;

    }

 

    public int compareTo(Citizen other) {

        return this.name.compareTo(other.getName());

    }

 

    public String toString() {

        return name + "\t" + sex + "\t" + age + "\t" + id + "\t" + birthplace + "\n";

    }

}

運行結果如下:

 

 

 

 

 

實驗4:內部類語法驗證實驗

實驗程序1

編輯、調試運行教材246-247頁程序6-7,結合程序運行結果理解程序;

了解內部類的基本用法。

代碼如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

import java.awt.*;

import java.awt.event.*;

import java.util.*;

import javax.swing.*;

import javax.swing.Timer;

 

/**

 * This program demonstrates the use of inner classes.

 * @version 1.11 2015-05-12

 * @author Cay Horstmann

 */

public class InnerClassTest

{

   public static void main(String[] args)

   {

      TalkingClock clock = new TalkingClock(1000, true);

      clock.start();

 

      // keep program running until user selects "Ok"

      JOptionPane.showMessageDialog(null, "Quit program?");

      System.exit(0);

   }

}

 

/**

 * A clock that prints the time in regular intervals.

 */

class TalkingClock

{

   private int interval;

   private boolean beep;

 

   /**

    * Constructs a talking clock

    * @param interval the interval between messages (in milliseconds)

    * @param beep true if the clock should beep

    */

   public TalkingClock(int interval, boolean beep)

   {

      this.interval = interval;

      this.beep = beep;

   }

 

   /**

    * Starts the clock.

    */

   public void start()

   {

      ActionListener listener = new TimePrinter();

      Timer t = new Timer(interval, listener);

      t.start();

   }

 

   public class TimePrinter implements ActionListener

   {

      public void actionPerformed(ActionEvent event)

      {

         System.out.println("At the tone, the time is " + new Date(interval)); if (beep) Toolkit.getDefaultToolkit().beep(); } } }

  運行結果如下:

 

 

 

實驗程序2

編輯、調試運行教材254頁程序6-8,結合程序運行結果理解程序;

掌握匿名內部類的用法。

代碼如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

import java.awt.*;

import java.awt.event.*;

import java.util.*;

import javax.swing.*;

import javax.swing.Timer;

 

/**

 * This program demonstrates anonymous inner classes.

 * @version 1.11 2015-05-12

 * @author Cay Horstmann

 */

public class AnonymousInnerClassTest

{

   public static void main(String[] args)

   {

      TalkingClock clock = new TalkingClock();

      clock.start(1000, true);

 

      // keep program running until user selects "Ok"

      JOptionPane.showMessageDialog(null, "Quit program?");

      System.exit(0);

   }

}

 

/**

 * A clock that prints the time in regular intervals.

 */

class TalkingClock

{

   /**

    * Starts the clock.

    * @param interval the interval between messages (in milliseconds)

    * @param beep true if the clock should beep

    */

   public void start(int interval, boolean beep)

   {

      ActionListener listener = new ActionListener()

         {

            public void actionPerformed(ActionEvent event)

            {

               System.out.println("At the tone, the time is " + new Date());

               if (beep) Toolkit.getDefaultToolkit().beep();

            }

         };

      Timer t = new Timer(interval, listener);

      t.start();

   }

}

  運行結果如下:

 

 

 

實驗程序3

elipse IDE中調試運行教材257-258頁程序6-9,結合程序運行結果理解程序;

了解靜態內部類的用法。

代碼如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

/**

 * This program demonstrates the use of static inner classes.

 * @version 1.02 2015-05-12

 * @author Cay Horstmann

 */

public class StaticInnerClassTest

{

   public static void main(String[] args)

   {

      var values = new double[20];

      for (int i = 0; i < values.length; i++)

         values[i] = 100 * Math.random();

      ArrayAlg.Pair p = ArrayAlg.minmax(values);

      System.out.println("min = " + p.getFirst());

      System.out.println("max = " + p.getSecond());

   }

}

 

class ArrayAlg

{

   /**

    * A pair of floating-point numbers

    */

   public static class Pair

   {

      private double first;

      private double second;

 

      /**

       * Constructs a pair from two floating-point numbers

       * @param f the first number

       * @param s the second number

       */

      public Pair(double f, double s)

      {

         first = f;

         second = s;

      }

 

      /**

       * Returns the first number of the pair

       * @return the first number

       */

      public double getFirst()

      {

         return first;

      }

 

      /**

       * Returns the second number of the pair

       * @return the second number

       */

      public double getSecond()

      {

         return second;

      }

   }

 

   /**

    * Computes both the minimum and the maximum of an array

    * @param values an array of floating-point numbers

    * @return a pair whose first element is the minimum and whose second element

    * is the maximum

    */

   public static Pair minmax(double[] values)

   {

      double min = Double.POSITIVE_INFINITY;

      double max = Double.NEGATIVE_INFINITY;

      for (double v : values)

      {

         if (min > v) min = v;

         if (max < v) max = v;

      }

      return new Pair(min, max);

   }

}

  運行結果如下:

 

 

 

 三、實驗總結

本周的學習過程中,主要了解了接口,接口和繼承在某些方面比較相似,但是接口又在繼承的基礎上發展了一些優點,克服了java單繼承的缺點。在學習過程中,可能是因為接口並不是具體的類,它只是實現,所以感覺接口比繼承抽象一些,不太容易理解。但通過這周的學習以及實驗中對具體程序的運行,對接口有了一定的掌握。自己編寫飾演的過程中,在之前的基礎上有的接口等新內容,自己還是不能獨立完成,在同學的幫助下才勉強完成了實驗。在實驗課上老師講的克隆以及函數接口等,自己還沒有太掌握,在之后的學習中,一定會繼續深入學習。

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM