201871010117 石欣钰《面向对象程序设计(Java)》第十二周学习总结
阅读原文时间:2023年07月10日阅读:2

 

内容

这个作业属于哪个课程

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

这个作业的要求在哪里

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

作业学习目标

(1) 掌握Vetor、Stack、Hashtable三个类的用途及常用API;

(2)  掌握ArrayList、LinkList两个类的用途及常用API;

(3) 了解java集合框架体系组成;

(4) 掌握Java GUI中框架创建及属性设置中常用类的API;

(5) 了解Java GUI中2D图形绘制常用类的API;

**
第一部分:总结第九章、第十章理论知识(40分)**

第九章  集合

1.集合是储存对象的,长度可变,可以封装不同的对象

2.迭代器: 其实就是取出元素的方式(只能判断,取出,移除,无法增加)

就是把取出方式定义在集合内部,这样取出方式就可以直接访问集合内部的元素,那么取出方式就被定义成了内部类.

二每一个容器的数据结构不同,所以取出的动作细节也不一样.但是都有共性内容判断和取出,那么可以将共性提取,这些内部类都符合一个规则Iterator

Iterator it = list.iterator();

while(it.hasNext()){

System.out.println(it.next());

}

另一种是

for(Iterator it = it.iterator(); it.hasNext();){

System.out.printin(it.next());}

Collection:

(1).List:元素是有序的,元素可以重复.因为改集合体系有索引.

!--ArrayList:底层的数据结构使用的是数组结构 ,特点:查询速度快,但是增删慢.线程不同步

!--LinkedList:底层使用的是;链表数据结构,特点:增删速度快,查寻速度慢.

!--Vector:底层的数据结构使用的是数组结构 ,.线程同步,速度慢,被ArrayList替代l

list:特有方法,凡是可以操作角标的方法都是该体系特有的方法

增:add(index,element); addAll(index,Collection);

删:remove(index);

改:set(index,element);

查:get(index); subList(from,to); ListIterator();(重点)

注意:判断同一对象,equals方法

public boolean equals(Object obj){

if(!(obj instanceof Person))

return false;

Person p=new Person();

return this.name.equals(p.name)&&this.age==p.age;

}

(2). Set:元素是无序的(元素存入和取出的顺序是不一定一致的),不可以重复

!--HashSet:底层数据结构是哈希表

HashSet使如何保证元素唯一性的呢?

是通过元素的两个方法,hashcode和equals来完成

如果元素的HashCode相同才会判断equals是否为true,反の,不会调用

对于判断元素是否存在,以及删除等操作,依赖的方法是元素的hashcode和equals方法

!--TreeSet:

--------------------------------------------------------------------

1.toArray()方法:是遍历用的(把集合转变为数组)

public class ToArray {

public static void main(String[] args) {

Collection c=new ArrayList();

c.add("hello");

c.add("world");

c.add("java");

Object[] obj=c.toArray();

for(int x=0;x < obj.length;x++){

System.out.println(obj[x]);

}

}

}

1.1asList()方法,把数组转变为集合

//定义一个数组

//String[] s={"hello","world","java"};

//List<``String``> list=Arrays.asList(s);

//直接引用

List<``String``> list=Arrays.asList("hello","world");

for(String s1:list){

System.out.println(s1);

}

注意:虽然他可以把数组转变成集合,但是本质是数组,所以他的长度不能改变,不能增删

2.数组长度是length方法,字符串的长度是length(),集合求长度的方法是size.

3. Iterator迭代器是集合的特有遍历方法

while方法:(习惯用法)

Iterator it=list.iterator();//list是集合

while(it.hasNext()){ //判断是否有下一个数据

System.out.println(it.next());

}

for循环方法:(效率高,it用完就是垃圾)

for(Iterator it=c.iterator();it.hasNext();){

System.out.println(it.next());

注意:不能连续it.next(),使用一次就换一个对象

4.list集合特有的遍历方法:就是size和get()的结合

for(int x=0; x<list.size();x++){

System.out.println(list.get(x));

}

5.list特有的迭代器

ListIterator<``String``> lit=list.listIterator();

while(lit.hasNext()){

System.out.println((String)lit.next());

}

while(lit.hasPrevious()){

System.out.println((String)lit.previous());

}

注意:ListIterator可以实现逆向遍历,但是必须现正向遍历,否则无意义

6.HashTable和HashMap的区别

HashTable:线程安全,效率低,不允许null建和null值.

HashMap:线程不安全,效率高,允许null建和null值.

7.Collection和Collections的区别?

Collection:是单列集合的顶层接口,有子接口List和Set

Collections:是针对集合操作的工具类,有对集合进行排序和二分查找的方法

8.二分查找找不到,返回 -(最大索引+1)

二、图形程序设计

图形用户界面(GUI,Graphical User Interface )是指以图形化方式与用户进行交互的程序运行界面,例如MicrosoftWindows、Word等。

优点:更友好、更丰富,且提供灵活、强大的人机交互功能,成为当前应用程序设计的主流。

在GUI程序设计中,组件(Component)是GUI的基本组成元素,凡是能够以图形化方式显示在屏幕上并能与用户交互的对象均为组件。

如下图:均为GUI界面的组件

另外,在JDK的Java.awt包中定义了多种GUI组件类,如Window、Menu、Button、Label、TextField、Scrollbar等。

这些抽象类,定义了GUI 组件的基本特性和功能

由上图可以看出,GUI中的组件可分为:

 

其中,需要注意的是:

  1. Container类描述了容器组件的所有性质;

2.它继承于Component类,因此容器类对象本身也是一个组件,具有组件的所有性质,但反过来组件却不一定是容器;

3.控制组件要想显示出来必须放置在容器组件中

其中,容器类型的组件在java.awt包下可以见到。这里,需要注意在AWT中存在两种主要的容器类型:

1. java.awt.Window
描述的是一个没有边框和菜单栏、可自由停靠的顶层容器(是指不允许将其包含于其他的容器中),一般不直接使用该类,而是使用其子类Frame。

2.java.awt.Panel
最简单而常用的容器,可作为容器包含其他组件,但不能独立存在,必须被添加到其它容器中。

案例:

  示例1:第一个GUI应用程序。

importjava.awt.*;

classTestFirstFrame{

public static void main(String args[]){

Frame frame=new Frame("第一个图形用户界面应用程序");//容器

Label lbl=new Label("这是我的第一个图形用户界面!");//控制组件

lbl.setBackground(Color.pink);

frame.setLayout(new FlowLayout());

frame.add(lbl);       //将控制组件添加到容器中

frame.setSize(200,100);

frame.setVisible(true);

}

}

应注意的是:

1. Frame 默认的大小为刚好容纳下标题条和最小(大)化、关闭按钮,setSize()可设置Frame大小。

2.Frame窗口默认是不可见的,可使用setVisible(true|false)方法使之可见或隐藏。

3.组件在容器中的摆放位置由布局管理器决定,Frame使用setLayout()方法可以设置窗口的布局。

4.FlowLayout—流式布局管理,特点是组件在容器中按照加入次序逐行定位,行内从左到右,一行排满后换行。

实例2.容器组件Panel的使用。

Frame frame=new Frame("容器Panel的使用");

Panel panel=new Panel();

Button btn=new Button("确定");

panel.setBackground(Color.cyan);

panel.setSize(100,50);

panel.setLocation(40,40);

frame.setLayout(null);

frame.add(panel);

panel.add(btn);

frame.setLocation(80,100);

frame.setSize(200,100);

frame.setVisible(true);

这里,应注意:

1.   frame的默认布局理器被取消,人工设置了panel的尺寸大小和在容器中的位置;

2.setSize()方法用于设置组件尺寸大小,即宽度和高度,单位为像素;

3.setLocation()方法用于设置组件在容器中的位置,即组件的左上角,即组件的左上角顶点坐标,单位也是像素。

4.各个GUI容器都拥有自己的坐标系统(计算机的显示器屏幕也是一种GUI容器)

位置关系如图:

通过上图我们可以看到,布局在GUI程序设计中的地位是十分重要的。在GUI程序设计中容器对其中所包含组件的排列方式,包括组件的位置和大小的设定,被称为容器的布局(Layout)。它是指系统事先定义好的若干容器布局效果,使用它们可以方便地实现组件在容器的布局管理,并能够满足各种常规需要。例如,FlowLayout等。

注意:

 每一个容器都有默认的布局管理器,在创建一个容器对象时,同时也会创建一个相应的默认布局管理器对象,用户也可以随时为容器创建和设置新的布局管理器。 
方法:

容器对象.setLayout(布局管理器对象) 
布局管理器  容器对象.getLayout()

 因此,了解常用布局管理器就显得十分重要

FlowLayout:流式布局,是Panel(及其子类)类型容器的默认布局管理器类型。

布局效果:组件在容器中按照加入次序逐行定位,行内从左到右,一行排满后换行。组件按原始大小进行显示。

构造方法
public FlowLayout()//默认居中对齐,5个像素的水平和垂直间距
public FlowLayout(int align)//指定对齐方式
public FlowLayout(int align,int hgap,int vgap)//组件的水平和垂直间距

其中,对齐方式可以使用FlowLayout类中定义静态常量来设定,主要包括:
FlowLayout.LEFT     左对齐
FlowLayout.RIGHT    右对齐
FlowLayout.CENTER     居中对齐

示例1:流式布局的使用。

f.setLayout(new FlowLayout());

f.add(button1);

f.add(button2);

f.add(button3);

   效果如图:

      

注意:

 当容器f的尺寸被重置时,其中组件的位置也随之进行了调整,但组件的尺寸维持不变。

BorderLayout:边界布局,是Window及其子类类型容器的默认布局管理器。

布局效果:将整个容器范围划分成East、West、South、North、Center五个区域,组件只能被添加到指定的区域。

   如图:

值得注意的是:

  1. 每个区域只能加入一个组件,如加入多个,则先前加入的组件会被遗弃 。

  2. 在使用边界布局的容器中,组件的尺寸也被布局管理器强行控制,即与其所在区域的尺寸相同。

构造方法
public BorderLayout()
public BorderLayout(int hgap,int vgap)

示例2:BorderLayout的使用。

f.setLayout(new BorderLayout());//该语句去掉也可,Frame默认布局为BorderLayout

//向容器的不同方位添加组件,也可使用BorderLayout中定义的String常量来表示,例,NORTH、SOUTH、WEST、EAST等。

f.add(btnNorth,"North");

f.add(btnSouth,"South");

f.add(btnWest,"West");

    f.add(btnEast,"East");

f.add(btnCenter,"Center");//如不指名组件的加入位置,则默认加入到Center区域。

注意:

1.当容器的尺寸发生变化时,其中各组件相对位置不变,尺寸随所在区域进行缩放调整;

2.调整原则:北、南两个区域只能在水平方向缩放(宽度可调),东、西两个区域只能在垂直方向缩放(高度可调),中部区域都可缩放。

在实际学习过程中,我们需要了解Conpoment类的基本属性和操作方法:

第二部分:实验部分

实验1 导入第9章示例程序,测试程序并进行代码注释。

测试程序1:

使用JDK命令运行编辑、运行以下三个示例程序,结合运行结果理解程序;

掌握Vetor、Stack、Hashtable三个类的用途及常用API。

示例程序1代码如下:

//示例程序1

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){

Vector<Cat> cats= new Vector<Cat>();

for``(``int i=``0``; i<``7``; i++)

cats.addElement(``new Cat(i));

for``(``int i=``0``; i<cats.size(); i++)

(cats.elementAt(i)).print();

}

}

程序运行结果如下:

例程序2代码如下:

//示例程序2

import java.util.*;

public class Stacks

{

static String[] months={``"金"``,``"银"``,``"铜"``,``"铁"``};

public static void main(String[] args){

Stack<String> stk = new Stack<String> ();

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

stk.push(months[i]);

System.out.println(stk);

System.out.println(``"element 2=" + stk.elementAt(``2``));

while``(!stk.empty())

System.out.println(stk.pop());

}

}

程序运行结果如下:

示例程序3代码如下:

//示例程序3

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))

((Counter)ht.get(r)).i++;

else

ht.put(r, new Counter());

}

System.out.println(ht);

}

}

程序运行结果如下:

Vetor、Stack、Hashtable三个类的用途:

(1)Vector类:Vector类类似长度可变的数组。 Vector中只能存放对象。 Vector的元素通过下标进行访问。

(2)Stack类:Stack类是Vector的子类。 Stack类描述堆栈数据结构,即LIFO。

(3)Hashtable类:Hashtable通过键来查找元素。Hashtable用散列码(hashcode)来确定键。

测试程序2:

使用JDK命令编辑运行ArrayListDemo和LinkedListDemo两个程序,结合程序运行结果理解程序;

程序代码如下:

ArrayListDemo:

import java.util.*;

public class ArrayListDemo {

public static void main(String[] argv) {

ArrayList al = new ArrayList();

// Add lots of elements to the ArrayList...

al.add(``new Integer(``11``));

al.add(``new Integer(``12``));

al.add(``new Integer(``13``));

al.add(``new String(``"hello"``));

// First print them out using a for loop.

System.out.println(``"Retrieving by index:"``);

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

System.out.println(``"Element " + i + " = " + al.get(i));

}

}

}

运行结果如下:

LinkedListDemo:

import java.util.*;

public class LinkedListDemo {

public static void main(String[] argv) {

LinkedList l = new LinkedList();

l.add(``new Object());

l.add(``"Hello"``);

l.add(``"zhangsan"``);

ListIterator li = l.listIterator(``0``);

while (li.hasNext())

System.out.println(li.next());

if (l.indexOf(``"Hello"``) < 0``)

System.err.println(``"Lookup does not work"``);

else

System.err.println(``"Lookup works"``);

}

}

运行结果如下:

在Elipse环境下编辑运行调试教材360页程序9-1,结合程序运行结果理解程序;

掌握ArrayList、LinkList两个类的用途

及常用API。

程序代码如下:

package JavaTest;

import java.util.*;

/**
* This program demonstrates operations on linked lists.
* @version 1.12 2018-04-10
* @author Cay Horstmann
*/
public class test
{
public static void main(String[] args)
{
var a = new LinkedList();
a.add("Amy");
a.add("Carl");
a.add("Erica");

var b = new LinkedList();
b.add("Bob");
b.add("Doug");
b.add("Frances");
b.add("Gloria");

// 将单词从B合并为A

ListIterator aIter = a.listIterator();
Iterator bIter = b.iterator();

while (bIter.hasNext())
{
if (aIter.hasNext()) aIter.next();
aIter.add(bIter.next());
}

System.out.println(a);

// 从B中删除每个第二个单词

bIter = b.iterator();
while (bIter.hasNext())
{
bIter.next(); // 跳过一个元素
if (bIter.hasNext())
{
bIter.next(); // 跳过下一个元素
bIter.remove(); // 删除该元素
}
}

System.out.println(b);

// 批量操作:从A中删除B中的所有单词

a.removeAll(b);

System.out.println(a);
}
}

运行结果如下:

ArrayList、LinkList两个类的用途:

(1)ArrayList 类提供了快速的基于索引的成员访问方式,对尾部成员的增加和删除支持较好。使用 ArrayList 创建的集合,允许对集合中的元素进行快速的随机访问,不过,向 ArrayList 中插入与删除元素的速度相对较慢。

(2)LinkedList 类采用链表结构保存对象,这种结构的优点是便于向集合中插入或者删除元素。需要频繁向集合中插入和删除元素时,使用 LinkedList 类比 ArrayList 类效果高,但是 LinkedList 类随机访问元素的速度则相对较慢。

实验2导入第10章示例程序,测试程序并进行代码注释。

测试程序1:

运行下列程序,观察程序运行结果。

程序代码如下:

import javax.swing.*;

public class SimpleFrameTest

{

public static void main(String[] args)

{

JFrame&nbsp; frame = new JFrame();

frame.setBounds(``0``, 0``,``300``, 200``);

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

frame.setVisible(``true``);

}

}

运行结果如下:

在elipse IDE中调试运行教材407页程序10-1,结合程序运行结果理解程序;与上面程序对比,思考异同;

掌握空框架创建方法;

了解主线程与事件分派线程概念;

掌握GUI顶层窗口创建技术。

程序代码如下:

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``);``//调用setVisible(true)显示一个组件

});

}

}

class SimpleFrame extends JFrame

{

private static final int DEFAULT_WIDTH = 300``;

private static final int DEFAULT_HEIGHT = 200``;

//构造器将框架大小设置为300*200像素

public SimpleFrame()

{

setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);

}

}

运行结果如下:

创建空框架:

1)在Java中,常采用框架(Frame)创建初始界面,即GUI的顶层窗口

2)AWT库中有一个基于对等体的Frame类。

3)该类的Swing版本为JFrame,JFrame是Frame子类。

测试程序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();``//调用Toolkit类的静态方法getDefaultToolkit得到一个Toolkit对象

Dimension screenSize = kit.getScreenSize();``//调用getScreenSize方法,这个方法以Dimension对象的形式返回屏幕的大小

int screenHeight = screenSize.height;

int screenWidth = screenSize.width;

//Dimension对象同时用公有实例变量width和height保存着屏幕的宽度和高度

setSize(screenWidth / 2``, screenHeight / 2``);``//将框架大小设定为上面取值的50%

setLocationByPlatform(``true``);``//告知窗口系统定位框架

//使用工具箱加载图像,然后将图像设置为框架的图标

Image img = new ImageIcon(``"icon.gif"``).getImage();

setIconImage(img);

}

}运行结果如下:

框架定位与框架属性
定位:
  常用Component类的setLocation和setBounds方法
常用属性:
  Title:框架标题
  IconImage:框架图标

测试程序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``);``//调用setVisible(true)显示一个组件

});

}

}

/**

* A frame that contains a message panel.

*/

//调用pack方法使用框架中填入的组件的首选大小

class NotHelloWorldFrame extends JFrame

{

public NotHelloWorldFrame()

{

add(``new NotHelloWorldComponent());

pack();

}

}

/**

* A component that displays a message.

*/

//覆盖getPreferredSize方法,返回一个有首选宽度和高度的Dimension类对象

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``;

//构造器将框架大小设置为300*200像素

public void paintComponent(Graphics g)

{

g.drawString(``"Not a Hello, World program"``, MESSAGE_X, MESSAGE_Y);

//用drawString方法调用,显示文本是一种特殊的绘图:在原始窗口大约水平1/4,垂直1/2的位置显示字符串Not a Hello, World program

}

public Dimension getPreferredSize()

{

return new Dimension(DEFAULT_WIDTH, DEFAULT_HEIGHT);

}

}

运行结果如下:

实验总结:在这周,我们学习了集合雨gui初步,就是以图形的方式呈现的用户界面,编程从命令行转移到了窗口,编程水平可以更进一步,通过运行示例程序,我对gui的概念更加清晰了,对于这样的“画图",让我体会到了Java的乐趣,但是知识掌握的还不够牢固,今后还需要多多编程,多多练习,才能有所提高。