201871010134-周英杰 《面向对象程序设计(java)》第十二周学习总结
项目 | 内容 |
这个作业属于哪个课程 | https://www.cnblogs.com/nwnu-daizh/ |
这个作业要求在哪里 | https://www.cnblogs.com/lily-2018/p/11441372.html |
作业学习目标 |
(1) 掌握Vetor、Stack、Hashtable三个类的用途及常用API; (2) 掌握ArrayList、LinkList两个类的用途及常用API。 (3) 掌握Java GUI中框架创建及属性设置中常用类的API; (4) 应用结对编程(Pair programming),体验程序开发中的两人合作。 |
第一部分:理论知识总结
第九章;
1.栈(Stack)也是一种特殊的线性表,是一种后进先出 (LIFO)的结构。栈是限定仅在表尾进行插入和删除运算的线性表,表尾称为栈顶(top),表头称为(bottom)。栈的物理存储可以用顺序存储结构,也可以用链式存储结构。
2.队列(Queue)是限定所有的插入只能在表的一端进行 ,而所有的删除都在表的另一端进行的线性表。表中允许插入的一端称为队尾(Rear),允许删除的一端称为队头(Front)。队列的操作是按先进先出(FIFO)的原则进行的。队列的物理存储可以用顺序存储结构,也可以用链式存储结构。
3.一般将数据结构分为两大类:线性数据结构和非线性数据结构。线性数据结构:线性表、栈、队列、串、数组和文件。非线性数据结构:树和图。线性表按其存储结构可分为顺序表和链表;用顺序存储结构存储的线性表称为顺序表;顺序表将线性表中的数据元素依次存放在某个存储区域中。一维数组就是用顺序方式存储的线性表。用链式存储结构存储的线性表称为链表。
4.集合框架:JAVA集合类库的统一架构。集合类的作用:Java的集合类提供了一些基本数据结构的支持。集合类的使用: Java的集合类包含在java.util包中。集合类的特点一:只容纳对象。注意:数组可以容纳基本数据类型数据和对象。如果集合类中想使用基本数据类型,又想利用集合类的灵活性,可以把基本数据类型数据封装成该数据类型的包装器对象,然后放入集合中处理。特点二:集合类容纳的对象都是Object类的实例,一旦把一个对象置入集合类中,它的类信息将丢失,这样设计的目的是为了集合类的通用性。因为Object类是所有类的祖先,所以可以在这些集合中存放任何类的对象而不受限制,但在使用集合成员之前必须对它重新造型。
5.JAVA的集合框架实现对各种数据结构的封装,以降低对数据管理与处理的难度。所谓框架就是一个类库的集合,框架中包含很多超类,编程者创建这些超类的子类可较方便的设计设计程序所需的类。
6.Map接口用来维持很多“键-值”对,以便通过键来查找相应的值。HashMap基于散列表实现(替代Hashtable)。TreeMap在一个二叉树的基础上实现(map)是一个存储关键字和值的关联或关键字/值对的对象。给定一个关键字,可以得到它的值。关键字和值都是对象。关键字必须是唯一的。但值是可以被复制的。Map接口映射唯一关键字到值。关键字(key)是以后用于检索值的对象。给定一个关键字和一个值,可以存储这个值到一个Map对象中。当这个值被存储以后,就可以使用它的关键字来检索它,Map循环使用两个基本操作:get( )和put( )。使用 put( )方法可以将一个指定了关键字和值的值加入映射。为了得到值可以通过将关键字作为参数来调用 get( )方法。调用返回该值。Map接口的实现类主要有HashMap,TreeMap,Hashtable,Properties。HashMap对key进行散TreeMap按照key进行排序。和Set类似,HashMap的速度通常都比TreeMap快,只有在需要排序的功能的时候,才使用TreeMap。
7.Vector类类似长度可变的数组。Vector中只能存放对象。Vector的元素通过下标进行访问。 Vector类关键属性:capacity表示集合最多能容纳的元素个数。capacityIncrement表示每次增加多少容量。size表示集合当前元素个数。Stack类是Vector的子类。Stack类描述堆栈数据结构,即LIFO。Hashtable通过键来查找元素。Hashtable用散列码(hashcode)来确定键。所有对象都有一个散列码,可以通过Object类的hashCode()方法获得。
8.集合框架中的基本接口:Collection:集合层次中的根接口,JDK未提供这个接口的直接实现类。
Set:不能包含重复的元素。对象可能不是按存放的次序存放,也就是说不能像数组一样按索引的方式进行访问,SortedSet是一个按照升序排列元素的Set。List的明显特征是它的元素都有一个确定的顺序。实现它的类有ArrayList和LinkedList。ArrayList中的元素在内存中是顺序存储的。LinkedList中的元素在内存中是以链表方式存储的。
TreeSet是一个有序集合,TreeSet中元素将照升序排列,缺省是按照自然顺序进行排列,意味着TreeSet中元素要实现Comparable接口。可以在构造TreeSet对象时,传递实现了 Comparator接口的比较器对象。HashSet是基于Hash算法实现的,其性能通常都优于TreeSet。通常使用HashSet,需要排序的功能时,使用TreeSet。
第十章:
1.Java的抽象口工具箱( Abstract WindowToolkit, AWT)包含在java.awt包中,它提供了许多用来设计GUI的组件类和容器类。
2.AWT库处理用户界面元素的方法:把图形元素的创建和行为委托给本地GUI工具箱进行处理。
3.Swing用户界面库是非基于对等体的GUI工具箱。Swing具有更丰富并且更方便的用户界面元素集合。Swing对底层平台的依赖很少,因此与平台相关的bug很少。Swing会带来交叉平台上的统一视觉体验。Swing类库被放在 javax.swing 包里。
4.大部分AWT组件都有其 Swing的等价组件。Swing组件的名字一般是在AWT组件名前面添加一个字母“J”,如:JButton,JFrame,JPanel等。
5.通常把由Component类的子类或间接子类创建的对象称为一个组件
6.Swing 组件层次关系
7..组件类的常用API
java.awt.Component 1.0
– boolean isVisible() 检查组件是否可见
– void setVisible(boolean b) 设置组件可见
– void setSize(int width,int height) 把组件缩放到指定宽度和高度
– void setBounds(int x,int y,int width,int height) 移动并缩放组件
– Dimension getSize() 得到组件的大小
– void setSize(Dimension d) 把组件缩放到指定的大小
– void setLocation(int x,int y)
8.容器是Java中能容纳和排列组件的组件。常用的容器是框架(Frame,JFrame)。
Container类提供了一个方法add(),用来在容器类 组件对象中添加其他组件。
容器本身也是一个组件,可以把一个容器添加到 另一个容器里,实现容器嵌套。
框架定位:常用Component类的setLocation和setBounds方法。常用属性:Title:框架标题;IconImage:框架图标。
确定框架大小:通过调用Toolkit类的方法来得到屏幕尺寸信息。
Jframe的结构:它由根面板、层级面板、玻璃面板和内容面板(content pane)四层面板构成。
Swing程序员最关心的是内容面板,也称为内容窗格。
在AWT中可调用add()方法把组件直接添加到AWT Frame中,在Swing中组件则添加到内容窗格里。
其中内容窗格是用来添加组件的,添加代码如下:Container contentPane = getContentPane(); Component c=…; contentPane.add(c);
用户也可以自行创建一个组件类,并在组件上进行绘制,此时需要重载paintComponent()。用户的自建组件也可添加到内容窗格里。
paintComponent(Graphics g)定义在JComponent类中,该方法在窗口需要重新绘图时(如扩大窗口或极小化窗口),被系统自动调用.
paintComponent()方法被调用时,系统就自动产生一个Graphics类型的参数,传递给paintComponent方法中的参数g。
第二部分:实验部分
实验1: 导入第9章示例程序,测试程序并进行代码注释。
测试程序1:
使用JDK命令运行编辑、运行以下三个示例程序,结合运行结果理解程序;
掌握Vetor、Stack、Hashtable三个类的用途及常用API。
1.示例程序1
代码如下:
package demo; import java.util.Vector; class Cat { private int catNumber; Cat(int i) { catNumber = i; } void print() { System.out.println("Cat #" + catNumber); } } public class Cats{ public static void main(String[] args){ //创建了一个Cat类型的Vector对象集合 Vector<Cat> cats= new Vector<Cat>(); //使用addElement方法向及集合中添加7个元素 for(int i=0; i<7; i++) cats.addElement(new Cat(i)); //size()方法会返回集合中元素的个数 //elementAt()方法获取指定位置上的元素 for(int i=0; i<cats.size(); i++) (cats.elementAt(i)).print(); } }
运行结果如下:
2.示例程序2
代码如下:
package demo; import java.util.*; public class Stacks { static String[] months={"金","银","铜","铁"}; public static void main(String[] args){ //创建一个String类型的Stack对象集合 Stack<String> stk = new Stack<String>(); //将字符串数组中的元素压入栈中 for(int i=0; i<months.length; i++) stk.push(months[i]); //输出栈对象 System.out.println(stk); //取出栈中位置为2的元素,此时栈中元素仍是按照字符串数组中的顺序排放 System.out.println("element 2=" + stk.elementAt(2)); //弹出栈中的所有元素 while(!stk.empty()) System.out.println(stk.pop()); } }
运行结果如下:
3.示例程序3
代码如下:
package demo; import java.util.*; class Counter { int i = 1; public String toString() { return Integer.toString(i); } } public class Statistics { public static void main(String[] args) { //创建一个哈希表对象 Hashtable ht = new Hashtable(); for (int i = 0; i < 10000; i++) { Integer r = new Integer((int) (Math.random() * 20)); //测试指定的对象是否是此哈希表的键 if(ht.containsKey(r)) //get():返回指定键映射到的值,将返回的值强制转变为Counter类对象,并将值+1; ((Counter)ht.get(r)).i++; else //映射指定的键处指定的值到哈希表里 ht.put(r, new Counter()); } //System.out.println(ht); //使用forEach()输出哈希表中的键值对 ht.forEach((k,v)-> System.out.println("key="+k+", value="+v)); } }
运行结果如下:
测试程序2:
● 使用JDK命令编辑运行ArrayListDemo和LinkedListDemo两个程序,结合程序运行结果理解程序;
1>.ArrayListDemo类
package demo; import java.util.*; public class ArrayListDemo { public static void main(String[] argv) { //创建一个ArrayList类对象 ArrayList al = new ArrayList(); // 增添一些元素到ArrayList类中 al.add(new Integer(11)); al.add(new Integer(12)); al.add(new Integer(13)); al.add(new String("hello")); // 使用for循环输出它们的值 System.out.println("Retrieving by index:"); for (int i = 0; i < al.size(); i++) { System.out.println("Element " + i + " = " + al.get(i)); } } }
运行结果如下:
2>.LinkedListDemo类
package demo; import java.util.*; public class LinkedListDemo { public static void main(String[] argv) { //创建一个LinkedList对象 LinkedList l = new LinkedList(); l.add(new Object()); l.add("Hello"); l.add("zhangsan"); //LinkedList类的listIterator方法返回了一个实现ListIterator接口的迭代器对象 ListIterator li = l.listIterator(0); //遍历链表中的每一个元素 while (li.hasNext()) System.out.println(li.next()); //indexof()方法返回与指定元素相等的元素在列表中第一次出现的位置,如果没有这样的元素将返回-1 if (l.indexOf("Hello") < 0) //Hello在列表中出现的位置是1>0 System.err.println("Lookup does not work"); else System.err.println("Lookup works"); } }
运行结果如下:
●在Elipse环境下编辑运行调试教材360页程序9-1,结合程序运行结果理解程序;
●掌握ArrayList、LinkList两个类的用途及常用API。
代码如下:
package linkedList; import java.util.*; /** * This program demonstrates operations on linked lists. * @version 1.12 2018-04-10 * @author Cay Horstmann */ public class LinkedListTest { public static void main(String[] args) { var a = new LinkedList<String>(); a.add("Amy"); a.add("Carl"); a.add("Erica"); var b = new LinkedList<String>(); b.add("Bob"); b.add("Doug"); b.add("Frances"); b.add("Gloria"); // merge the words from b into a ListIterator<String> aIter = a.listIterator(); //LinkedList类的listIterator方法返回了一个实现ListIterator接口的迭代器对象 Iterator<String> bIter = b.iterator(); //LinkedList类的iterator方法返回了一个实现Iterator接口的迭代器对象 //将b中的每个元素插入到a中相应元素的后面 while (bIter.hasNext()) { if (aIter.hasNext()) aIter.next(); aIter.add(bIter.next()); } System.out.println(a); // remove every second word from b bIter = b.iterator(); while (bIter.hasNext()) { bIter.next(); // skip one element if (bIter.hasNext()) { bIter.next(); // skip next element bIter.remove(); // remove that element } } System.out.println(b); // 删除a中所有的b元素 a.removeAll(b); System.out.println(a); } }
运行结果如下:
实验2:导入第10章示例程序,测试程序并进行代码注释。
测试程序1:
运行下列程序,观察程序运行结果。
● 在elipse IDE中调试运行教材407页程序10-1,结合程序运行结果理解程序;与上面程序对比,思考异同;
● 掌握空框架创建方法;
● 了解主线程与事件分派线程概念;
● 掌握GUI顶层窗口创建技术。
1>示例程序:
代码如下:
package demo; import javax.swing.*; public class SimpleFrameTest { public static void main(String[] args) { //创建一个框架对象 JFrame frame = new JFrame(); //设置框架的位置和宽高 frame.setBounds(0, 0,300, 200); //设置框架是否具有可关闭功能 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //设置框架是否可见 frame.setVisible(true); } }
运行结果如下:
2>教材程序
package simpleFrame; import java.awt.*; import javax.swing.*; /** * @version 1.34 2018-04-10 * @author Cay Horstmann */ public class SimpleFrameTest { public static void main(String[] args) { EventQueue.invokeLater(() -> { //创建一个框架对象 var frame = new SimpleFrame(); //设置框架是否具有可关闭功能 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //设置框架是否可见 frame.setVisible(true); }); } } class SimpleFrame extends JFrame { private static final int DEFAULT_WIDTH = 300; private static final int DEFAULT_HEIGHT = 200; public SimpleFrame() { //设置框架的宽高 setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT); } }
运行结果如下:
测试程序2:
● 在elipse IDE中调试运行教材412页程序10-2,结合运行结果理解程序;
● 掌握确定框架常用属性的设置方法。
代码如下:
package sizedFrame; import java.awt.*; import javax.swing.*; /** * @version 1.35 2018-04-10 * @author Cay Horstmann */ public class SizedFrameTest { public static void main(String[] args) { EventQueue.invokeLater(() -> { var frame = new SizedFrame(); frame.setTitle("SizedFrame"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setVisible(true); }); } } class SizedFrame extends JFrame { public SizedFrame() { // 获取屏幕尺寸 Toolkit kit = Toolkit.getDefaultToolkit(); Dimension screenSize = kit.getScreenSize(); int screenHeight = screenSize.height; int screenWidth = screenSize.width; // 设置框架宽度、高度并让平台拾取屏幕位置 setSize(screenWidth / 2, screenHeight / 2); setLocationByPlatform(true); // 设置帧图标 Image img = new ImageIcon("icon.gif").getImage(); setIconImage(img); } }
运行结果如下:
测试程序3:
● 在elipse IDE中调试运行教材418页程序10-3,结合运行结果理解程序;
● 掌握在框架中添加组件;
● 掌握自定义组件的用法。
代码如下:
package notHelloWorld; import javax.swing.*; import java.awt.*; /** * @version 1.34 2018-04-10 * @author Cay Horstmann */ public class NotHelloWorld { public static void main(String[] args) { EventQueue.invokeLater(() -> { var frame = new NotHelloWorldFrame(); frame.setTitle("NotHelloWorld"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setVisible(true); }); } } /** * A frame that contains a message panel. */ class NotHelloWorldFrame extends JFrame { public NotHelloWorldFrame() { //添加一个绘制消息的组件到框架中 add(new NotHelloWorldComponent()); /*在框架中填入一个或多个组件时,如果你只想使用它们的首选大小(默认大小), 可以调用pack方法而不是setSize方法*/ pack(); } } /** * 一个显示消息的组件. */ class NotHelloWorldComponent extends JComponent { public static final int MESSAGE_X = 75; public static final int MESSAGE_Y = 100; private static final int DEFAULT_WIDTH = 300; private static final int DEFAULT_HEIGHT = 200; //paintComponent方法中有一个Graphics类型的参数,这个参数保存着用于绘制图像和文本的设置 public void paintComponent(Graphics g) { //显示文本是一种特殊的绘图。在Graphics类中有一个drawString方法。 g.drawString("Not a Hello, World program", MESSAGE_X, MESSAGE_Y); } //组件应该告诉用户它有多大。覆盖getPreferredSize方法,返回一个有首选宽度和高度的Dimension public Dimension getPreferredSize() { return new Dimension(DEFAULT_WIDTH, DEFAULT_HEIGHT); } }
运行结果如下:
实验总结:
1.Vector类类似长度可变的数组。Vector中只能存放对象。Vector的元素通过下标进行访问。 Vector类关键属性:capacity表示集合最多能容纳的元素个数。capacityIncrement表示每次增加多少容量。size表示集合当前元素个数。Stack类是Vector的子类。Stack类描述堆栈数据结构,即LIFO。Hashtable通过键来查找元素。Hashtable用散列码(hashcode)来确定键。所有对象都有一个散列码,可以通过Object类的hashCode()方法获得。
2. ArrayList:可以将其看作是能够自动增长容量的数组。利用ArrayList的toArray()返回一个数组。Arrays.asList()返回一个列表。LinkedList是采用双向循环链表实现的。利用LinkedList实现栈(stack)、队列(queue)、双向队列 (double-ended queue )。ArrayList底层采用数组完成,而LinkedList则是以一般的双向链表(double-linked list)完成,其内每个对象除了数据本身外,还有两个引用,分别指向前一个元素和后一个元素。如果经常在 List 中进行插入和删除操作,应该使用LinkedList,否则,使用ArrayList将更加快速。
3. TreeSet是一个有序集合,TreeSet中元素将按照升序排列,缺省是按照自然顺序进行排列,意味着TreeSet中元素要实现Comparable接口。可以在构造TreeSet对象时,传递实现了 Comparator接口的比较器对象。HashSet是基于Hash算法实现的,其性能通常都优于TreeSet。通常使用HashSet,需要排序的功能时,使用TreeSet。
AWT(Abstract Window Toolkit)包括了很多类和接口,用于Java Application的GUI(Graphics User Interface)编程。使用AWT所涉及的类一般在java.awt包及其子包中,GUI的各种元素(如:窗口,按钮,文本框等)由Java类来实现。Component类和Container类是AWT中的两个核心类。Java的图形用户界面的最基本组成部分是Component类,Component类及其子类的对象用来描述以图形化的方式显示在屏幕上并能与用户进行交互的GUI元素,例如,一个按钮,一个标签等。一般的Component类对象不能独立地显示出来,必须将放在某一的Container类对象中才可以显示出来Container类是Component抽象的子类,Container子类对象可以容纳别的Component对象。
Graphics2D类仍然保留Graphics类的绘图方法,同时增加了许多新方法。新方法将几何图形(线段、圆等)作为一个对象来绘制。在java.awt.geom包中声明的一系列类,分别用于创建各种身体图形对象。Font属性:所有的文本都使用能表现文字的样式图形渲染。当前的字体决定了字体的形状。使用继java.awt.Graphics的getFont()方法和setFont()方法来操纵字体。尽管设置字体相对简单的工作,Java 2D还是为文本描绘提供了丰富的选项。
要使用Java 2D库绘制图形,就需要获得一个Graphics2D类对象,它是Graphics类的子类。可以在paintComponent方法中强转获得一个Graphics2D的类对象。
我的感受:本周主要学习了与图形用户界面设计有关的知识,通过本章的学习我了解了如何用一些组件去画字,图形。了解了创建框架时的一些常用API,图形用户界面的一些基础的设计操作,比如窗口显示不同图形,文字等等,觉得很有意思;但实际用这些知识自己去设计图形还是会有一定的难度。通过练习题集练习学过的内容,对学过的知识进行了再巩固,加深了理解。