第八周学习总结
第一部分:理论知识
一、接口、lambda和内部类; Comparator与comparable接口;
1.comparable接口的方法是compareTo,只有一个参数;comparator接口的方法是compare,有两个参数。
comparator自定义比较器。comparable实现接口。
2.对象克隆
1 深拷贝与浅拷贝。如果对象是不可变的,那么默认的浅拷贝也没有问题;否则,就要使用深拷贝。
2)默认的克隆方法是浅拷贝,clone方法是Object的一个protected方法。
3) 要让一个对象可以克隆,则需要如下步骤:
a.实现cloneable接口
b.重定义clone方法,并指定public访问修饰符。
c.重定义的clone方法要逐一拷贝每一个域。
4.如果一个要clone的对象没有实现cloneable接口,那么编译器就会抛出一个CloneNotSupportedException异常。
形似cloneable这样的接口叫做标记接口,标记接口没有实现任何的方法,他的作用只是允许在类型查询中使用instanceOf。
即便默认浅拷贝能够满足要求,还是徐亚需要实现Cloneable接口,将clone重新定义为public,再调用super.clone().
5.lambda表达式
1) 传代码而非传值。
2) lambda的语法规则:(参数)->以及一个表达式
3)如果计算无法在一个表达式中完成,那么就使用{}。
4)即使lambda没有参数,任然要提供空括号,就算无参方法一样。
5)如果可以推导出一个lambda表达式的参数类型,则可以忽略其类型。
6)如果方法只要一个参数,而且这个 参数的类型可以推导得出,那么甚至可以省略小括号。
6)无需指定lambda表达式的返回类型。lambda表达式返回类型总可以由上下文推导出。
7)如果一个lambda表达式只在某些分支返回一个值,而在另一些分支不返回,这是不合法的。
8)只有一个抽象方法的接口,称为函数式接口。
9)lambda表达式中捕获的变量必须是最终变量,这个变量初始化之后就不能再为他赋新值,不能做更改。
10)在lambda表达式中,声明一个与局部变量同名的参数或局部变量是不可合法的。
11)在一个lambda表达式中使用this关键字,是指创建这个lambda表达式的方法的this参数。
6.内部类
作用:内部类方法可以访问外围类的数据,包括私有的数据.
内部类可以对同一个包种的其他类隐藏起来.
使用anonymous内部类定义回调函数类.
第二部分:实验部分
1、实验目的与要求
(1) 掌握接口定义方法;
(2) 掌握实现接口类的定义要求;
(3) 掌握实现了接口类的使用要求;
(4) 掌握程序回调设计模式;
(5) 掌握Comparator接口用法;
(6) 掌握对象浅层拷贝与深层拷贝方法;
(7) 掌握Lambda表达式语法;
(8) 了解内部类的用途及语法要求。
2、实验内容和步骤
实验1: 导入第6章示例程序,测试程序并进行代码注释。
测试程序1:
l 编辑、编译、调试运行阅读教材214页-215页程序6-1、6-2,理解程序并分析程序运行结果;
l 在程序中相关代码处添加新知识的注释。
l 掌握接口的实现用法;
l 掌握内置接口Compareable的用法。
1 package interfaces; 2 3 public class Employee implements Comparable<Employee> 4 { 5 //声明属性; 6 private String name; 7 private double salary; 8 //构造方法; 9 public Employee(String name, double salary) 10 { 11 this.name = name; 12 this.salary = salary; 13 } 14 //Name属性访问器; 15 public String getName() 16 { 17 return name; 18 } 19 //Salary属性访问器; 20 public double getSalary() 21 { 22 return salary; 23 } 24 //计算工资方法; 25 public void raiseSalary(double byPercent) 26 { 27 double raise = salary * byPercent / 100; 28 salary += raise; 29 } 30 31 /** 32 * Compares employees by salary 33 * @param other another Employee object 34 * @return a negative value if this employee has a lower salary than 35 * otherObject, 0 if the salaries are the same, a positive value otherwise 36 */ 37 38 public int compareTo(Employee other)//compareTo方法; 39 { 40 return Double.compare(salary, other.salary);//包装器 调用compare方法; 41 } 42 }
1 package interfaces; 2 3 import java.util.*; 4 5 /** 6 * This program demonstrates the use of the Comparable interface. 7 * @version 1.30 2004-02-27 8 * @author Cay Horstmann 9 */ 10 public class EmployeeSortTest 11 { 12 public static void main(String[] args) 13 { 14 //构建数组对象; 15 Employee[] staff = new Employee[3]; 16 //用三个staff对象填充数组; 17 staff[0] = new Employee("Harry Hacker", 35000); 18 staff[1] = new Employee("Carl Cracker", 75000); 19 staff[2] = new Employee("Tony Tester", 38000); 20 21 Arrays.sort(staff);//按字母排序方法; 22 23 // print out information about all Employee objects 24 for (Employee e : staff) 25 System.out.println("name=" + e.getName() + ",salary=" + e.getSalary()); 26 } 27 }
测试程序2:
l 编辑、编译、调试以下程序,结合程序运行结果理解程序;
1 interface A 2 { 3 double g=9.8; 4 void show( ); 5 } 6 class C implements A 7 { 8 public void show( ) 9 {System.out.println("g="+g);} 10 } 11 12 class InterfaceTest 13 { 14 public static void main(String[ ] args) 15 { 16 A a=new C( ); 17 a.show( ); 18 System.out.println("g="+C.g); 19 } 20 }
1 public interface A 2 { 3 double g=9.8; 4 void show( ); 5 } 6 7 8 9 10 public class C implements A 11 { 12 public void show( ) 13 {System.out.println("g="+g);} 14 } 15 16 17 18 19 public class InterfaceTest 20 { 21 public static void main(String[ ] args) 22 { 23 A a=new C( ); 24 a.show( ); 25 System.out.println("g="+C.g); 26 } 27 }
测试程序3:
l 在elipse IDE中调试运行教材223页6-3,结合程序运行结果理解程序;
l 26行、36行代码参阅224页,详细内容涉及教材12章。
l 在程序中相关代码处添加新知识的注释。
l 掌握回调程序设计模式;
1 package timer; 2 3 /** 4 @version 1.01 2015-05-12 5 @author Cay Horstmann 6 */ 7 8 import java.awt.*; 9 import java.awt.event.*; 10 import java.util.*; 11 import javax.swing.*; 12 import javax.swing.Timer; 13 // 解决与java.util.Timer的矛盾 14 15 public class TimerTest 16 { 17 public static void main(String[] args) 18 { 19 ActionListener listener = new TimePrinter(); 20 21 //构造一个调用侦听器的计时器; 22 //每十秒一次; 23 Timer t = new Timer(10000, listener); 24 t.start(); 25 26 JOptionPane.showMessageDialog(null, "Quit program?"); 27 System.exit(0); 28 } 29 } 30 31 class TimePrinter implements ActionListener 32 { 33 public void actionPerformed(ActionEvent event) 34 { 35 System.out.println("At the tone, the time is " + new Date()); 36 Toolkit.getDefaultToolkit().beep(); 37 } 38 }
测试程序4:
l 调试运行教材229页-231页程序6-4、6-5,结合程序运行结果理解程序;
l 在程序中相关代码处添加新知识的注释。
l 掌握对象克隆实现技术;
l 掌握浅拷贝和深拷贝的差别。
1 package clone; 2 3 import java.util.Date; 4 import java.util.GregorianCalendar; 5 6 public class Employee implements Cloneable 7 { 8 9 private String name; 10 private double salary; 11 private Date hireDay; 12 13 public Employee(String name, double salary) 14 { 15 this.name = name; 16 this.salary = salary; 17 hireDay = new Date(); 18 } 19 // 20 public Employee clone() throws CloneNotSupportedException 21 { 22 23 Employee cloned = (Employee) super.clone();//返回Object对象后强制类型转换; 24 25 // 克隆可变部分; 26 cloned.hireDay = (Date) hireDay.clone(); 27 28 return cloned; 29 } 30 31 /** 32 * Set the hire day to a given date. 33 * @param year the year of the hire day 34 * @param month the month of the hire day 35 * @param day the day of the hire day 36 */ 37 public void setHireDay(int year, int month, int day) 38 { 39 Date newHireDay = new GregorianCalendar(year, month - 1, day).getTime(); 40 41 // 实例字段变异实例; 42 hireDay.setTime(newHireDay.getTime()); 43 } 44 45 public void raiseSalary(double byPercent) 46 { 47 double raise = salary * byPercent / 100; 48 salary += raise; 49 } 50 51 public String toString() 52 { 53 return "Employee[name=" + name + ",salary=" + salary + ",hireDay=" + hireDay + "]"; 54 } 55 }
实验2: 导入第6章示例程序6-6,学习Lambda表达式用法。
l 调试运行教材233页-234页程序6-6,结合程序运行结果理解程序;
l 在程序中相关代码处添加新知识的注释。
l 将27-29行代码与教材223页程序对比,将27-29行代码与此程序对比,体会Lambda表达式的优点。
1 package Lambda; 2 3 import java.util.*; 4 5 import javax.swing.*; 6 import javax.swing.Timer; 7 8 /** 9 * This program demonstrates the use of lambda expressions. 10 * @version 1.0 2015-05-12 11 * @author Cay Horstmann 12 */ 13 public class LambdaTest 14 { 15 public static void main(String[] args) 16 { 17 //定义并初始化string类数组; 18 String[] planets = new String[] { "Mercury", "Venus", "Earth", "Mars", 19 "Jupiter", "Saturn", "Uranus", "Neptune" }; 20 //排序前输出; 21 System.out.println(Arrays.toString(planets)); 22 System.out.println("Sorted in dictionary order:"); 23 Arrays.sort(planets); 24 System.out.println(Arrays.toString(planets));//按字母顺序排序输出; 25 System.out.println("Sorted by length:"); 26 //按单词长度排序后,使用lambda表达式; 27 Arrays.sort(planets, (first, second) -> first.length() - second.length()); 28 System.out.println(Arrays.toString(planets));// 29 //方法引用;lambda表达式; 30 Timer t = new Timer(1000, event -> 31 System.out.println("The time is " + new Date()));//每隔一秒输出当前时间; 32 t.start(); 33 34 // 继续运行程序,知道用户选择OK; 35 JOptionPane.showMessageDialog(null, "Quit program?"); 36 System.exit(0); 37 } 38 }
实验3: 编程练习
l 编制一个程序,将身份证号.txt 中的信息读入到内存中;
l 按姓名字典序输出人员信息;
l 查询最大年龄的人员信息;
l 查询最小年龄人员信息;
l 输入你的年龄,查询身份证号.txt中年龄与你最近人的姓名、身份证号、年龄、性别和出生地;
l 查询人员中是否有你的同乡。
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.Collections; import java.util.Scanner; public class Search{ private static ArrayList<Person> Personlist1; public static void main(String[] args) { Personlist1 = new ArrayList<>(); Scanner scanner = new Scanner(System.in); File file = new File("E:\\面向对象程序设计Java\\实验\\实验六\\身份证号.txt"); try { FileInputStream F = new FileInputStream(file); BufferedReader in = new BufferedReader(new InputStreamReader(F)); 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 place =linescanner.nextLine(); Person Person = new Person(); Person.setname(name); Person.setid(id); Person.setsex(sex); int a = Integer.parseInt(age); Person.setage(a); Person.setbirthplace(place); Personlist1.add(Person); } } catch (FileNotFoundException e) { System.out.println("查找不到信息"); e.printStackTrace(); } catch (IOException e) { System.out.println("信息读取有误"); e.printStackTrace(); } boolean isTrue = true; while (isTrue) { System.out.println("******************************************"); System.out.println("1:按姓名字典顺序输出信息;"); System.out.println("2:查询最大年龄与最小年龄人员信息;"); System.out.println("3:按省份找你的同乡;"); System.out.println("4:输入你的年龄,查询年龄与你最近人的信息;"); System.out.println("5:退出"); System.out.println("******************************************"); int type = scanner.nextInt(); switch (type) { case 1: Collections.sort(Personlist1); System.out.println(Personlist1.toString()); break; case 2: int max=0,min=100;int j,k1 = 0,k2=0; for(int i=1;i<Personlist1.size();i++) { j=Personlist1.get(i).getage(); if(j>max) { max=j; k1=i; } if(j<min) { min=j; k2=i; } } System.out.println("年龄最大:"+Personlist1.get(k1)); System.out.println("年龄最小:"+Personlist1.get(k2)); break; case 3: System.out.println("place?"); String find = scanner.next(); String place=find.substring(0,3); String place2=find.substring(0,3); for (int i = 0; i <Personlist1.size(); i++) { if(Personlist1.get(i).getbirthplace().substring(1,4).equals(place)) { System.out.println("你的同乡:"+Personlist1.get(i)); } } break; case 4: System.out.println("年龄:"); int yourage = scanner.nextInt(); int close=ageclose(yourage); int d_value=yourage-Personlist1.get(close).getage(); System.out.println(""+Personlist1.get(close)); break; case 5: isTrue = false; System.out.println("再见!"); break; default: System.out.println("输入有误"); } } } public static int ageclose(int age) { int m=0; int max=53; int d_value=0; int k=0; for (int i = 0; i < Personlist1.size(); i++) { d_value=Personlist1.get(i).getage()-age; if(d_value<0) d_value=-d_value; if (d_value<max) { max=d_value; k=i; } } return k; } } //jiekouwenjiaan public class Person implements Comparable<Person> { private String name; private String id; private int age; private String sex; 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 int getage() { return age; } public void setage(int age) { // int a = Integer.parseInt(age); this.age= age; } public String getsex() { return sex; } public void setsex(String sex) { this.sex= sex; } public String getbirthplace() { return birthplace; } public void setbirthplace(String birthplace) { this.birthplace= birthplace; } public int compareTo(Person o) { return this.name.compareTo(o.getname()); } public String toString() { return name+"\t"+sex+"\t"+age+"\t"+id+"\t"; } }
实验4:内部类语法验证实验
实验程序1:
l 编辑、调试运行教材246页-247页程序6-7,结合程序运行结果理解程序;
l 了解内部类的基本用法。
1 package innerClass; 2 3 import java.awt.*; 4 import java.awt.event.*; 5 import java.util.*; 6 import javax.swing.*; 7 import javax.swing.Timer; 8 9 /** 10 * This program demonstrates the use of inner classes. 11 * @version 1.11 2015-05-12 12 * @author Cay Horstmann 13 */ 14 public class InnerClassTest 15 { 16 public static void main(String[] args) 17 { 18 TalkingClock clock = new TalkingClock(1000, true); 19 clock.start(); 20 21 // 保持程序运行知道用户选择OK; 22 JOptionPane.showMessageDialog(null, "Quit program?"); 23 System.exit(0); 24 } 25 } 26 27 /** 28 * A clock that prints the time in regular intervals. 29 */ 30 class TalkingClock 31 { 32 private int interval; 33 private boolean beep; 34 35 /** 36 * Constructs a talking clock 37 * @param interval the interval between messages (in milliseconds) 38 * @param beep true if the clock should beep 39 */ 40 public TalkingClock(int interval, boolean beep) 41 { 42 this.interval = interval; 43 this.beep = beep; 44 } 45 46 /** 47 * Starts the clock. 48 */ 49 public void start() 50 { 51 ActionListener listener = new TimePrinter(); 52 Timer t = new Timer(interval, listener); 53 t.start(); 54 } 55 56 public class TimePrinter implements ActionListener 57 { 58 public void actionPerformed(ActionEvent event) 59 { 60 System.out.println("At the tone, the time is " + new Date()); 61 if (beep) Toolkit.getDefaultToolkit().beep(); 62 } 63 } 64 }
实验程序2:
l 编辑、调试运行教材254页程序6-8,结合程序运行结果理解程序;
l 了解匿名内部类的用法。
1 import java.awt.*; 2 import java.awt.event.*; 3 import java.util.*; 4 import javax.swing.*; 5 import javax.swing.Timer; 6 7 /** 8 * This program demonstrates anonymous inner classes. 9 * @version 1.11 2015-05-12 10 * @author Cay Horstmann 11 */ 12 public class AnonymousInnerClassTest 13 { 14 public static void main(String[] args) 15 { 16 TalkingClock clock = new TalkingClock(); 17 clock.start(1000, true); 18 19 // 保持程序运行知道用户选择OK; 20 JOptionPane.showMessageDialog(null, "Quit program?"); 21 System.exit(0); 22 } 23 } 24 25 /** 26 * A clock that prints the time in regular intervals. 27 */ 28 class TalkingClock 29 { 30 /** 31 * Starts the clock. 32 * @param interval the interval between messages (in milliseconds) 33 * @param beep true if the clock should beep 34 */ 35 //匿名内部类; 36 public void start(int interval, boolean beep) 37 { 38 ActionListener listener = new ActionListener() 39 { 40 public void actionPerformed(ActionEvent event) 41 { 42 System.out.println("At the tone, the time is " + new Date()); 43 if (beep) Toolkit.getDefaultToolkit().beep(); 44 } 45 }; 46 Timer t = new Timer(interval, listener); 47 t.start(); 48 } 49 }
l 了解匿名内部类的用法。
实验程序3:
l 在elipse IDE中调试运行教材257页-258页程序6-9,结合程序运行结果理解程序;
l 了解静态内部类的用法。
1 package staticInnerClass; 2 3 /** 4 * This program demonstrates the use of static inner classes. 5 * @version 1.02 2015-05-12 6 * @author Cay Horstmann 7 */ 8 public class StaticInnerClassTest 9 { 10 public static void main(String[] args) 11 { 12 double[] d = new double[20]; 13 for (int i = 0; i < d.length; i++) 14 d[i] = 100 * Math.random(); 15 ArrayAlg.Pair p = ArrayAlg.minmax(d); 16 System.out.println("min = " + p.getFirst()); 17 System.out.println("max = " + p.getSecond()); 18 } 19 } 20 21 class ArrayAlg 22 { 23 /** 24 * A pair of floating-point numbers 25 */ 26 public static class Pair 27 { 28 private double first; 29 private double second; 30 31 /** 32 * Constructs a pair from two floating-point numbers 33 * @param f the first number 34 * @param s the second number 35 */ 36 public Pair(double f, double s) 37 { 38 first = f; 39 second = s; 40 } 41 42 /** 43 * Returns the first number of the pair 44 * @return the first number 45 */ 46 public double getFirst() 47 { 48 return first; 49 } 50 51 /** 52 * Returns the second number of the pair 53 * @return the second number 54 */ 55 public double getSecond() 56 { 57 return second; 58 } 59 } 60 61 /** 62 * Computes both the minimum and the maximum of an array 63 * @param values an array of floating-point numbers 64 * @return a pair whose first element is the minimum and whose second element 65 * is the maximum 66 */ 67 public static Pair minmax(double[] values) 68 { 69 double min = Double.POSITIVE_INFINITY; 70 double max = Double.NEGATIVE_INFINITY; 71 for (double v : values) 72 { 73 if (min > v) min = v; 74 if (max < v) max = v; 75 } 76 return new Pair(min, max); 77 } 78 }
第三部分:总结
1.接口和内部类很nice啊!真好!!!我很喜欢!
2.编程三:1)写switch-case语句的时候又忘了一个break,结果输出很“一路顺畅”;
2)在写的时候没有想到一些不合法的输入及对应输出,在调试时不小心键入了个不合适的内容才发觉,借鉴了别人的代码才解决;
3. 学习了Comparator与comparable接口
4..Lambda表达式简化了很多
5.学习了深层拷贝跟渐层拷贝的区别
6.关于本章的理论知识和编程练习还在继续........创造Java语言的人,Respect!!!