本章咱們學習了泛型程序設計技術,理解了泛型概念,掌握了泛型類的定義與使用和泛型方法的聲明與使用。在驗證明驗中,經過對代碼的解讀,更好的學習了泛型程序<T>的使用,雖然不是很熟練,但仍是作出來了,感受依舊存在些小問題,在接下來的實驗中要更好的解決。還有在本身編程時,還存在很大問題。在以後的學習中,我會多練習程序去了解這些知識。
201871010111-劉佳華《面向對象程序設計(java)》第十一週學習總結java
實驗九 泛型程序設計技術編程
實驗時間 2019-11-8數組
1、實驗目的與要求安全
(1) 理解泛型概念;ide
(2) 掌握泛型類的定義與使用;post
(3) 瞭解泛型方法的聲明與使用;學習
(4) 掌握泛型接口的定義與實現;測試
(5) 理解泛型程序設計,理解其用途ui
第一部分:理論知識總結this
一、泛型程序設計概念
二、泛型類的聲明及實例化的方法
三、泛型方法的定義
public class ArrayTool { public static<T> void insert(T[] e, int p) { //請本身添加代碼 } public static<T> T valueAt(T[] e , int p) { //請本身添加代碼 } }
四、泛型接口的定義
public interfance IPool<T> { T get(); int add(T t); }
泛型變量的限定:
1.定義泛型變量的上界
extends關鍵字所聲明的上界既能夠是一個類,也能夠是一個接口
2.定義泛型變量的下界
– 經過使用super關鍵字能夠固定泛型參數的類型爲某種類型或者其超類
– 當程序但願爲一個方法的參數限定類型時,一般可使用下限通配符
泛型類的約束與侷限性(*)
不能用基本類型實例化類型參數
運行時類型查詢只適用於原始類型
不能拋出也不能捕獲泛型類實例
參數化類型的數組不合法
不能實例化類型變量
泛型類的靜態上下文中類型變量無效注意擦除後的
泛型類型的繼承規則(*)
Java中的數組是協變的(covariant)。
通配符類型
通配符
– 「?」符號代表參數的類型能夠是任何一種類型,它和參數T的含義是有區別的。T表示一種未知類型,而「?」表示任何一種類型。這種通配符通常有如下三種用法:
– 單獨的?,用於表示任何類型。
– ? extends type,表示帶有上界。
– ? super type,表示帶有下界。
第二部分:實驗內容和步驟
實驗1: 導入第8章示例程序,測試程序並進行代碼註釋。
測試程序1:
l 編輯、調試、運行教材311、312頁代碼,結合程序運行結果理解程序;
l 在泛型類定義及使用代碼處添加註釋;
l 掌握泛型類的定義及使用。
代碼以下:
1 package pair1; 2 3 /** 4 * @version 1.00 2004-05-10 5 * @author Cay Horstmann 6 */ 7 public class Pair<T> //用戶自定義泛型pair類 8 { 9 private T first; 10 private T second; 11 12 public Pair() { first = null; second = null; } 13 public Pair(T first, T second) { this.first = first; this.second = second; } 14 15 public T getFirst() { return first; } 16 public T getSecond() { return second; } 17 18 public void setFirst(T newValue) { first = newValue; } 19 public void setSecond(T newValue) { second = newValue; } 20 }
1 package pair1; 2 3 /** 4 * @version 1.01 2012-01-26 5 * @author Cay Horstmann 6 */ 7 public class PairTest1 8 { 9 public static void main(String[] args) 10 { 11 String[] words = { "Mary", "had", "a", "little", "lamb" }; 12 Pair<String> mm = ArrayAlg.minmax(words); 13 System.out.println("min = " + mm.getFirst()); 14 System.out.println("max = " + mm.getSecond()); 15 } 16 } 17 18 class ArrayAlg 19 { 20 /** 21 * Gets the minimum and maximum of an array of strings. 22 * @param a an array of strings 23 * @return a pair with the min and max values, or null if a is null or empty 24 */ 25 public static Pair<String> minmax(String[] a)//獲取字符串數組的最小值和最大值。 26 { 27 if (a == null || a.length == 0) return null; 28 String min = a[0]; 29 String max = a[0]; 30 for (int i = 1; i < a.length; i++) 31 { 32 if (min.compareTo(a[i]) > 0) min = a[i]; 33 if (max.compareTo(a[i]) < 0) max = a[i]; 34 } 35 return new Pair<>(min, max);// 具備最小值和最大值的對,若是a爲null或空,則爲null 36 } 37 }
運行結果:
測試程序2:
l 編輯、調試運行教材315頁 PairTest2,結合程序運行結果理解程序;
l 在泛型程序設計代碼處添加相關注釋;
l 瞭解泛型方法、泛型變量限定的定義及用途。
1 package pair2; 2 3 /** 4 * @version 1.00 2004-05-10 5 * @author Cay Horstmann 6 */ 7 public class Pair<T> 8 { 9 private T first; 10 private T second; 11 12 public Pair() { first = null; second = null; } 13 public Pair(T first, T second) { this.first = first; this.second = second; } 14 15 public T getFirst() { return first; } 16 public T getSecond() { return second; } 17 18 public void setFirst(T newValue) { first = newValue; } 19 public void setSecond(T newValue) { second = newValue; } 20 }
1 package pair2; 2 3 import java.time.*; 4 5 /** 6 * @version 1.02 2015-06-21 7 * @author Cay Horstmann 8 */ 9 public class PairTest2 10 { 11 public static void main(String[] args) 12 { 13 LocalDate[] birthdays = 14 { 15 LocalDate.of(1906, 12, 9), // G. Hopper 16 LocalDate.of(1815, 12, 10), // A. Lovelace 17 LocalDate.of(1903, 12, 3), // J. von Neumann 18 LocalDate.of(1910, 6, 22), // K. Zuse 19 }; 20 Pair<LocalDate> mm = ArrayAlg.minmax(birthdays);//建立localdate類型的pair對象 21 System.out.println("min = " + mm.getFirst()); 22 System.out.println("max = " + mm.getSecond()); 23 } 24 } 25 26 class ArrayAlg 27 { 28 /** 29 Gets the minimum and maximum of an array of objects of type T. 30 @param a an array of objects of type T 31 @return a pair with the min and max values, or null if a is null or empty 32 */ 33 public static <T extends Comparable> Pair<T> minmax(T[] a)//使用extends關鍵字,定義泛型變量的上界,調用Comparable接口 34 { 35 if (a == null || a.length == 0) return null; 36 T min = a[0]; 37 T max = a[0]; 38 for (int i = 1; i < a.length; i++) 39 { 40 if (min.compareTo(a[i]) > 0) min = a[i]; 41 if (max.compareTo(a[i]) < 0) max = a[i]; 42 } 43 return new Pair<>(min, max); 44 } 45 }
運行截圖:
測試程序3:
l 用調試運行教材335頁 PairTest3,結合程序運行結果理解程序;
瞭解通配符類型的定義及用途。
1 package pair3; 2 3 /** 4 * @version 1.00 2004-05-10 5 * @author Cay Horstmann 6 */ 7 public class Pair<T> 8 { 9 private T first; 10 private T second; 11 12 public Pair() { first = null; second = null; } 13 public Pair(T first, T second) { this.first = first; this.second = second; } 14 15 public T getFirst() { return first; } 16 public T getSecond() { return second; } 17 18 public void setFirst(T newValue) { first = newValue; } 19 public void setSecond(T newValue) { second = newValue; } 20 }
1 package pair3; 2 3 import java.time.*; 4 5 public class Employee 6 { 7 private String name; 8 private double salary; 9 private LocalDate hireDay; 10 11 public Employee(String name, double salary, int year, int month, int day) 12 { 13 this.name = name; 14 this.salary = salary; 15 hireDay = LocalDate.of(year, month, day); 16 } 17 18 public String getName() 19 { 20 return name; 21 } 22 23 public double getSalary() 24 { 25 return salary; 26 } 27 28 public LocalDate getHireDay() 29 { 30 return hireDay; 31 } 32 33 public void raiseSalary(double byPercent) 34 { 35 double raise = salary * byPercent / 100; 36 salary += raise; 37 } 38 }
1 package pair3; 2 3 public class Manager extends Employee 4 { 5 private double bonus; 6 7 /** 8 @param name the employee's name 9 @param salary the salary 10 @param year the hire year 11 @param month the hire month 12 @param day the hire day 13 */ 14 public Manager(String name, double salary, int year, int month, int day) 15 { 16 super(name, salary, year, month, day); 17 bonus = 0; 18 } 19 20 public double getSalary() 21 { 22 double baseSalary = super.getSalary(); 23 return baseSalary + bonus; 24 } 25 26 public void setBonus(double b) 27 { 28 bonus = b; 29 } 30 31 public double getBonus() 32 { 33 return bonus; 34 } 35 }
1 package pair3; 2 3 /** 4 * @version 1.01 2012-01-26 5 * @author Cay Horstmann 6 */ 7 public class PairTest3 8 { 9 public static void main(String[] args) 10 { 11 var ceo = new Manager("Gus Greedy", 800000, 2003, 12, 15); 12 var cfo = new Manager("Sid Sneaky", 600000, 2003, 12, 15); 13 var buddies = new Pair<Manager>(ceo, cfo); 14 printBuddies(buddies); 15 16 ceo.setBonus(1000000); 17 cfo.setBonus(500000); 18 Manager[] managers = { ceo, cfo }; 19 20 var result = new Pair<Employee>(); 21 minmaxBonus(managers, result); 22 System.out.println("first: " + result.getFirst().getName() 23 + ", second: " + result.getSecond().getName()); 24 maxminBonus(managers, result); 25 System.out.println("first: " + result.getFirst().getName() 26 + ", second: " + result.getSecond().getName()); 27 } 28 29 public static void printBuddies(Pair<? extends Employee> p)//? extends type,表示帶有上界 30 { 31 Employee first = p.getFirst(); 32 Employee second = p.getSecond(); 33 System.out.println(first.getName() + " and " + second.getName() + " are buddies.");//"?"在這兒是通配符,符號代表參數的類型能夠是任何一種類型,它和參數T的含義是有區別的 34 } 35 36 public static void minmaxBonus(Manager[] a, Pair<? super Manager> result) 37 { 38 if (a.length == 0) return; 39 Manager min = a[0]; 40 Manager max = a[0]; 41 for (int i = 1; i < a.length; i++) 42 { 43 if (min.getBonus() > a[i].getBonus()) min = a[i]; 44 if (max.getBonus() < a[i].getBonus()) max = a[i]; 45 } 46 result.setFirst(min); 47 result.setSecond(max); 48 } 49 //T表示一種未知類型,而「?」表示任何一種類型 50 public static void maxminBonus(Manager[] a, Pair<? super Manager> result) 51 { 52 minmaxBonus(a, result); 53 PairAlg.swapHelper(result); // swapHelper捕獲通配符類型 54 } 55 // 不能寫公共靜態<T超級管理器> ... 56 } 57 58 class PairAlg 59 { 60 public static boolean hasNulls(Pair<?> p) 61 { 62 return p.getFirst() == null || p.getSecond() == null; 63 } 64 65 public static void swap(Pair<?> p) { swapHelper(p); } 66 67 68 public static <T> void swapHelper(Pair<T> p) 69 { 70 T t = p.getFirst(); 71 p.setFirst(p.getSecond()); 72 p.setSecond(t); 73 } 74 }
運行結果:
實驗2:結對編程練習,將程序提交到PTA(2019面向對象程序設計基礎知識測試題(2))
(1) 編寫一個泛型接口GeneralStack,要求類中方法對任何引用類型數據都適用。GeneralStack接口中方法以下:
push(item); //如item爲null,則不入棧直接返回null。 pop(); //出棧,如爲棧爲空,則返回null。 peek(); //得到棧頂元素,如爲空,則返回null. public boolean empty();//如爲空返回true public int size(); //返回棧中元素數量 |
(2)定義GeneralStack的子類ArrayListGeneralStack,要求:
ü 類內使用ArrayList對象存儲堆棧數據,名爲list;
ü 方法: public String toString()//代碼爲return list.toString();
ü 代碼中不要出現類型不安全的強制轉換。
(3)定義Car類,類的屬性有:
private int id; private String name; |
方法:Eclipse自動生成setter/getter,toString方法。
(4)main方法要求
ü 輸入選項,有quit, Integer, Double, Car 4個選項。若是輸入quit,程序直接退出。不然,輸入整數m與n。m表明入棧個數,n表明出棧個數。而後聲明棧變量stack。
ü 輸入Integer,打印Integer Test。創建能夠存放Integer類型的ArrayListGeneralStack。入棧m次,出棧n次。打印棧的toString方法。最後將棧中剩餘元素出棧並累加輸出。
ü 輸入Double ,打印Double Test。剩下的與輸入Integer同樣。
ü 輸入Car,打印Car Test。其餘操做與Integer、Double基本同樣。只不過最後將棧中元素出棧,並將其name依次輸出。
特別注意:若是棧爲空,繼續出棧,返回null
輸入樣例
Integer 5 2 1 2 3 4 5 Double 5 3 1.1 2.0 4.9 5.7 7.2 Car 3 2 1 Ford 2 Cherry 3 BYD quit |
輸出樣例
Integer Test push:1 push:2 push:3 push:4 push:5 pop:5 pop:4 [1, 2, 3] sum=6 interface GeneralStack Double Test push:1.1 push:2.0 push:4.9 push:5.7 push:7.2 pop:7.2 pop:5.7 pop:4.9 [1.1, 2.0] sum=3.1 interface GeneralStack Car Test push:Car [id=1, name=Ford] push:Car [id=2, name=Cherry] push:Car [id=3, name=BYD] pop:Car [id=3, name=BYD] pop:Car [id=2, name=Cherry] [Car [id=1, name=Ford]] Ford interface GeneralStack |
代碼以下:
1 public interface GeneralStack<T> { 2 public T push(T item); //如item爲null,則不入棧直接返回null 3 public T pop(); //出棧,如爲棧爲空,則返回null。 4 public T peek(); //得到棧頂元素,如爲空,則返回null. 5 public boolean empty(); //如爲空返回true 6 public int size(); //返回棧中元素數量 7 }
1 public class ArrayListGeneralStack implements GeneralStack{ 2 ArrayList list =new ArrayList(); 3 4 public String toString(){ 5 return list.toString(); 6 } 7 @Override 8 public Object push(Object item) { 9 // TODO Auto-generated method stub 10 if (list.add(item)){ 11 return item; 12 }else { 13 return false; 14 } 15 } 16 17 @Override 18 public Object pop() { 19 // TODO Auto-generated method stub 20 if (list.size()==0){ 21 return null; 22 } 23 return list.remove(list.size()-1); 24 } 25 26 @Override 27 public Object peek() { 28 // TODO Auto-generated method stub 29 return list.get(list.size()-1); 30 } 31 32 @Override 33 public boolean empty() { 34 // TODO Auto-generated method stub 35 if (list.size()==0){ 36 return true; 37 }else { 38 return false; 39 } 40 } 41 42 @Override 43 public int size() { 44 // TODO Auto-generated method stub 45 return list.size(); 46 } 47 48 }
1 public class Car{ 2 private int id; 3 private String name; 4 public Car(int id, String name) { 5 this.id = id; 6 this.name = name; 7 } 8 @Override 9 public String toString() { 10 // TODO Auto-generated method stub 11 return "Car [" +"id=" + id +", name=" + name +"]"; 12 } 13 public int getId() { 14 return id; 15 } 16 public void setId(int id) { 17 this.id = id; 18 } 19 public String getName() { 20 return name; 21 } 22 public void setName(String name) { 23 this.name = name; 24 } 25 }
1 public class Test { 2 public static void main(String args[] ) { 3 Scanner S=new Scanner(System.in); 4 while(true) { 5 String sc=S.nextLine(); 6 if(sc.equals("quit")) { 7 break; 8 } 9 else if(sc.equals("Integer")) { 10 System.out.println("Integer Test"); 11 int count=S.nextInt(); 12 int pop_time=S.nextInt(); 13 ArrayListGeneralStack arrayListGeneralStack = new ArrayListGeneralStack(); 14 for (int i=0;i<count;i++){ 15 System.out.println("push:"+arrayListGeneralStack.push(S.nextInt())); 16 } 17 for (int i=0;i<pop_time;i++){ 18 System.out.println("pop:"+arrayListGeneralStack.pop()); 19 } 20 System.out.println(arrayListGeneralStack.toString()); 21 int sum=0; 22 int size=arrayListGeneralStack.size(); 23 for (int i=0;i<size;i++){ 24 sum+=(int)arrayListGeneralStack.pop(); 25 } 26 System.out.println("sum="+sum); 27 System.out.println("interface GeneralStack"); 28 } 29 else if (sc.equals("Double")) { 30 System.out.println("Double Test"); 31 int count=S.nextInt(); 32 int pop_time=S.nextInt(); 33 ArrayListGeneralStack arrayListGeneralStack = new ArrayListGeneralStack(); 34 for (int i=0;i<count;i++){ 35 System.out.println("push:"+arrayListGeneralStack.push(S.nextDouble())); 36 } 37 for (int i=0;i<pop_time;i++){ 38 System.out.println("pop:"+arrayListGeneralStack.pop()); 39 } 40 System.out.println(arrayListGeneralStack.toString()); 41 double sum=0; 42 int size=arrayListGeneralStack.size(); 43 for (int i=0;i<size;i++){ 44 sum+=(double)arrayListGeneralStack.pop(); 45 } 46 System.out.println("sum="+sum); 47 System.out.println("interface GeneralStack"); 48 } 49 else if (sc.equals("Car")){ 50 System.out.println("Car Test"); 51 int count=S.nextInt(); 52 int pop_time=S.nextInt(); 53 ArrayListGeneralStack arrayListGeneralStack = new ArrayListGeneralStack(); 54 for (int i=0;i<count;i++){ 55 int id=S.nextInt(); 56 String name=S.next(); 57 Car car = new Car(id,name); 58 System.out.println("push:"+arrayListGeneralStack.push(car)); 59 } 60 for (int i=0;i<pop_time;i++){ 61 System.out.println("pop:"+arrayListGeneralStack.pop()); 62 } 63 System.out.println(arrayListGeneralStack.toString()); 64 if (arrayListGeneralStack.size()>0){ 65 int size=arrayListGeneralStack.size(); 66 for (int i=0;i<size;i++){ 67 Car car=(Car) arrayListGeneralStack.pop(); 68 System.out.println(car.getName()); 69 } 70 } 71 System.out.println("interface GeneralStack"); 72 } 73 74 } 75 76 } 77 }
總體代碼以下:
1 package week11PartnerProgrem; 2 3 import java.util.ArrayList; 4 import java.util.Scanner; 5 6 interface GeneralStack<T> { 7 public T push(T item); //如item爲null,則不入棧直接返回null 8 public T pop(); //出棧,如爲棧爲空,則返回null。 9 public T peek(); //得到棧頂元素,如爲空,則返回null. 10 public boolean empty(); //如爲空返回true 11 public int size(); //返回棧中元素數量 12 } 13 class ArrayListGeneralStack implements GeneralStack{ 14 ArrayList list =new ArrayList(); 15 16 public String toString(){ 17 return list.toString(); 18 } 19 @Override 20 public Object push(Object item) { 21 // TODO Auto-generated method stub 22 if (list.add(item)){ 23 return item; 24 }else { 25 return false; 26 } 27 } 28 29 @Override 30 public Object pop() { 31 // TODO Auto-generated method stub 32 if (list.size()==0){ 33 return null; 34 } 35 return list.remove(list.size()-1); 36 } 37 38 @Override 39 public Object peek() { 40 // TODO Auto-generated method stub 41 return list.get(list.size()-1); 42 } 43 44 @Override 45 public boolean empty() { 46 // TODO Auto-generated method stub 47 if (list.size()==0){ 48 return true; 49 }else { 50 return false; 51 } 52 } 53 54 @Override 55 public int size() { 56 // TODO Auto-generated method stub 57 return list.size(); 58 } 59 60 } 61 62 class Car{ 63 private int id; 64 private String name; 65 public Car(int id, String name) { 66 this.id = id; 67 this.name = name; 68 } 69 @Override 70 public String toString() { 71 // TODO Auto-generated method stub 72 return "Car [" +"id=" + id +", name=" + name +"]"; 73 } 74 public int getId() { 75 return id; 76 } 77 public void setId(int id) { 78 this.id = id; 79 } 80 public String getName() { 81 return name; 82 } 83 public void setName(String name) { 84 this.name = name; 85 } 86 } 87 public class Test { 88 public static void main(String args[] ) { 89 Scanner S=new Scanner(System.in); 90 while(true) { 91 String sc=S.nextLine(); 92 if(sc.equals("quit")) { 93 break; 94 } 95 else if(sc.equals("Integer")) { 96 System.out.println("Integer Test"); 97 int count=S.nextInt(); 98 int pop_time=S.nextInt(); 99 ArrayListGeneralStack arrayListGeneralStack = new ArrayListGeneralStack(); 100 for (int i=0;i<count;i++){ 101 System.out.println("push:"+arrayListGeneralStack.push(S.nextInt())); 102 } 103 for (int i=0;i<pop_time;i++){ 104 System.out.println("pop:"+arrayListGeneralStack.pop()); 105 } 106 System.out.println(arrayListGeneralStack.toString()); 107 int sum=0; 108 int size=arrayListGeneralStack.size(); 109 for (int i=0;i<size;i++){ 110 sum+=(int)arrayListGeneralStack.pop(); 111 } 112 System.out.println("sum="+sum); 113 System.out.println("interface GeneralStack"); 114 } 115 else if (sc.equals("Double")) { 116 System.out.println("Double Test"); 117 int count=S.nextInt(); 118 int pop_time=S.nextInt(); 119 ArrayListGeneralStack arrayListGeneralStack = new ArrayListGeneralStack(); 120 for (int i=0;i<count;i++){ 121 System.out.println("push:"+arrayListGeneralStack.push(S.nextDouble())); 122 } 123 for (int i=0;i<pop_time;i++){ 124 System.out.println("pop:"+arrayListGeneralStack.pop()); 125 } 126 System.out.println(arrayListGeneralStack.toString()); 127 double sum=0; 128 int size=arrayListGeneralStack.size(); 129 for (int i=0;i<size;i++){ 130 sum+=(double)arrayListGeneralStack.pop(); 131 } 132 System.out.println("sum="+sum); 133 System.out.println("interface GeneralStack"); 134 } 135 else if (sc.equals("Car")){ 136 System.out.println("Car Test"); 137 int count=S.nextInt(); 138 int pop_time=S.nextInt(); 139 ArrayListGeneralStack arrayListGeneralStack = new ArrayListGeneralStack(); 140 for (int i=0;i<count;i++){ 141 int id=S.nextInt(); 142 String name=S.next(); 143 Car car = new Car(id,name); 144 System.out.println("push:"+arrayListGeneralStack.push(car)); 145 } 146 for (int i=0;i<pop_time;i++){ 147 System.out.println("pop:"+arrayListGeneralStack.pop()); 148 } 149 System.out.println(arrayListGeneralStack.toString()); 150 if (arrayListGeneralStack.size()>0){ 151 int size=arrayListGeneralStack.size(); 152 for (int i=0;i<size;i++){ 153 Car car=(Car) arrayListGeneralStack.pop(); 154 System.out.println(car.getName()); 155 } 156 } 157 System.out.println("interface GeneralStack"); 158 } 159 160 } 161 162 } 163 }
運行截圖:
第三部分:
本章咱們學習了泛型程序設計技術,理解了泛型概念,掌握了泛型類的定義與使用和泛型方法的聲明與使用。在驗證明驗中,經過對代碼的解讀,更好的學習了泛型程序<T>的使用,雖然不是很熟練,但仍是作出來了,感受依舊存在些小問題,在接下來的實驗中要更好的解決。還有在本身編程時,還存在很大問題。在以後的學習中,我會多練習程序去了解這些知識。