201871010128-杨丽霞《面向对象程序设计(Java)》第十二周学习总结
阅读原文时间:2023年07月11日阅读:3

201871010128-杨丽霞《面向对象程序设计(Java)》第十一周学习总结

项目

内容

这个作业属于哪个课程

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

9.1  Java中的集合框架

  1. 集合框架实现了对基本数据结构的封装。
    集合是一种包含多个元素,并提供对所包含元素操作方法的类,其包含的元素可以由同一类型的对象组成,也可以由不同类型的对象组成。
    集合类的使用:
    Java的集合类包含在java.util包中。import java.util.*;

Jdk版本中的集合类:vector,stack,hashtable

2.集合框架中的基本接口

9.2集合类及集合类的特点和作用

集合的两个顶级接口分别为:Collection和Map

Collection下有两个比较常用的接口分别是List(列表)和Set(集),其中List可以存储重复元素,元素是有序的(存取顺序一致),可以通过List脚标来获取指定元素;而Set不可以有重复元素,元素是无序的。

List接口中,比较常用的类有三个:ArrayList、Vactor、LinkedList。

ArrayList :线程不安全的,对元素的查询速度快。

Vector :线程安全的,多了一种取出元素的方式:枚举(Enumeration),但已被ArrayList取代。

LinkedList :链表结构,对元素的增删速度很快。

Set接口中,比较常用的类有两个:HashSet、TreeSet:

HashSet:要保证元素唯一性,需要覆盖掉Object中的equals和hashCode方法(因为底层是通过这两个方法来判断两个元素是否是同一个)。

TreeSet:以二叉树的结构对元素进行存储,可以对元素进行排序。

排序的两种方式:

1、元素自身具备比较功能,元素实现Comparable接口,覆盖compareTo方法。

2、建立一个比较器对象,该对象实现Comparator接口,覆盖compare方法,并将该对象作为参数传给TreeSet的构造函数(可以用匿名内部类)。

Map接口其特点是:元素是成对出现的,以键和值的形式体现出来,键要保证唯一性:常用类有:HashMap,Hashtable ,TreeMap。

HashMap:线程不安全等的,允许存放null键null值。

Hashtable:线程安全的,不允许存放null键null值。

TreeMap:可以对键进行排序(要实现排序方法同TreeSet)。

Collection和Map两个接口对元素操作的区别:

存入元素:

Collection接口下的实现类通过add方法来完成,而Map下是通过put方法来完成。

取出元素:

Collection接口下:List接口有两种方式:1、get(脚标);2、通过Iterator迭代方式获取元素;而Vactor多了一种枚举(Enumeration)的方式。Set接口通过迭代的方式获取元素。

Map接口下:先通地keySet获取键的系列,然后通过该系列使用Iterator迭代方式获取元素值

9.3  映射

映射的基本操作

java类库为映射提供了两个实现:HashMap和TreeMap。这两个类都实现了Map接口。每当往映射中添加对象时,必须同时提供一个键,这里,键是一个字符串,对应的值是Employee对象。

而且,键必须是唯一的,不能对同一个键存放两个值。

更新映射项

(1)可以用getOrDefault方法(2)调用putIfAbsent方法,只有当键原先存在时才会放入一个值。merge方法可以简化这个操作。

映射视图

集合框架可以得到映射的视图。这是实现了Collection接口或某个子接口的对象

9.4 视图与包装

通过使用视图(views)可以获得其他的实现了集合接口和映射表接口的对象。映射表类的keySet方法就是一个这样的实例。初看起来,好像这个方法创建了一个新集,并将映射表中的所有键都填进去,然后返回这个集。但是,情况并非如此。取而代之的是:keySet方法返回一个实现Set接口的类对象,这个类的方法对原映射表进行操作。这种集合称为视图。

Arrays类的静态方法asList将返回一个包装了普通Java数组的List包装器。这个方法可以将数组传递给一个期望得到列表或几个变元的方法。返回的对象不是ArrayList。

它是一个视图对象,带有访问底层数组的get和set方法。改变数组大小的所有方法(例如,与迭代器有关的add和remove方法)都会抛出一个Unsupported OperationException异常。
从Java SE 5.0开始,asList方法声明为一个具有可变数量参数的方法。除了可以传递一个数组之外,还可以将各个元素直接传递给这个方法。
9.5 算法
排序与混排

Collections类中的sort方法可以对实现了List接口的集合进行排序。这个方法假定列表元素实现了Comparable接口。如果想采用其他方式对列表进行排序,可以将Compaator对象作为第二个参数传递给sort方法。

如果想按照降序对列表进行排序,可以使用一种非常方便的静态方法Collections.reverseOrder()。这个方法将返回一个比较器,比较器则返回b.compareTo(a)。这个方法将根据元素类型的compareTo方法给定排序顺序。

第十章 图形程序设计
10.1 AWT与Swing概述

1.Java的抽象窗口工具箱(Abstract Window Toolkit, AWT)包含在java.awt包中,它提供了许多用来设计GUI的组件类和容器类
AWT库处理用户界面元素的方法:把图形元素的创建和行为委托给本地GUI工具箱进行处理。AWT库使用缺陷。菜单、滚动条和文本域等用户界面元素,在不同的平台上,操作行为上存在一些微妙的差异

2.Swing库具有更丰富且方便的用户界面元素集合。Swing对底层平台的依赖很少,因此与平台相关的bug很少。Swing会带来交叉平台上的统一视觉体验。Swing类库被放在javax.swing包里

3.AWT与Swing的关系
大部分AWT组件都有其Swing的等价组件。
Swing组件的名字一般是在AWT组件名前面添加一个字母“J”,如:JButton,JFrame,JPanel等。

10.2 创建框架
1、什么是组件
构成图形用户界面的元素
用图形表示(能在屏幕上显示,能和用户进行交互)Button、Checkbox、Scrollbar、Choice、Frame

通常把由Component类的子类或间接子类创建的对象称为一个组件。
例:Button  button = new Button();
例:TextField  textField = new TextField();
例:Label  label = new Label();

  1. 容器是Java中能容纳和排列组件的组件。
    常用的容器是框架(Frame,JFrame)
    例Frame  fra = new Frame(“这是一个窗口”);
    java.awt.Frame 类的常用API
    void setResizable(boolean b) 缩放框架
    void setTitle(String s) 设置框架标题void setIconImage(Image image) 将Image用作框架图标

Container类提供了一个方法add(),用来在容器类组件对象中添加其他组件。
 例:fra.add(button); 
 fra.add(textField);

3.添加组件
容器本身也是一个组件,可以把一个容器添加到另一个容器里,实现容器嵌套。
创建空框架 
在Java中,常采用框架Frame)创建初始界面,即GUI的顶层窗口 AWT库中有一个基于对等体的Frame类。 该类的Swing版本为JFrame,JFrame是Frame子类
框架定位与框架属性定位:
常用Component类的setLocation和setBounds方法
常用属性
Title:框架标题
IconImage:框架图标

4.用户也可以自行创建一个组件类,此时需要重载paintComponent()。
用户的自建组件也可添加到内容窗格paintComponent(Graphics g)定义在JComponent类中,该方法在窗口需要重新绘图时(如扩大窗口或极小化窗口),被系统自动调用.
paintComponent()方法被调用时,系统就自动产生一个Graphics类型的参数,传递给paintComponent方法中的参数g。
10.5 处理2D图形
一、Frame

1)Container getContentPane():返回这个Frame的内容窗格对象

2)void repaint():“尽可能快的”重新绘制组件(绘制2D图像时,即使缩小窗口后在恢复,图形仍在)

3)void paintComponent(Graphics g):覆盖这个方法来绘制自己的组件(这是继承JComponent时,如果集成式JPane,应该重写paint(Graphics g)的方法)

4)void pack():调整窗口大小,要考虑到其组件的首选大小

10.6 使用颜色

与颜色有关的常用方法:

(1)用类Color的构造方法Color(int R, int G,int B)创建一个颜色对象,参数R,G,B分别表示红色、绿色和蓝色,它们的取值是从0到255。

(2)用类Graphics的方法setColor(Color c),参数c的取值参见表12-1。

(3)用类Component的方法setBackground(Color c)设置背景颜色。因为小程序是组件类的子类,直接可用setBackground()方法改变背景色。

(4)用类Graphics的方法getColor()获取颜色

Java绘图中,显示文字的方法主要有三种:

(1)drawString(String str,int x,int y):在指定的位置显示字符串。

(2)drawChars(char data[],int offset,int length, int x, int y):在指定的位置显示字符数组中的文字,从字符数组的offset位置开始,最多显示length个字符。

(3)drawBytes(byte data[],int offset,int length,int x,int y), 在指定的位置显示字符数组中的文字,从字符数组的offset位置开始,最多显示length个字符。

第二部分:实验部分

实验1:测试程序1(6分)

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

掌握VetorStackHashtable三个类的用途及常用API

//示例程序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 cats= new Vector();
for(int i=; i<; i++) cats.addElement(new Cat(i)); for(int i=; i stk = new Stack ();
for(int i=; i<months.length; i++)
stk.push(months[i]);
System.out.println(stk);
System.out.println("element 2=" + stk.elementAt());
while(!stk.empty())
System.out.println(stk.pop());
}
}
//示例程序3
import java.util.*;
class Counter {
int i = ;
public String toString() {
return Integer.toString(i);
}
}

public class Statistics {
public static void main(String[] args) {
Hashtable ht = new Hashtable();
for (int i = ; i < ; i++) {
Integer r = new Integer((int) (Math.random() * ));
if(ht.containsKey(r))
((Counter)ht.get(r)).i++;
else
ht.put(r, new Counter());
}
System.out.println(ht);
}
}

运行截图如下:

总结:

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

Stack类(Vector的子类):它描述堆栈数据结构。(所有对象都有一个散列码,可以通过Object类的hashCode方法获得。)

Hashtable 类:Hashtable 继承 Map 接口,实现了一个基于 Key-Value 映射的哈希表。任何非空(non-null)的对象都可作为 Key 或者 Value。添加数据使用 Put(Key,Value),取出数据使用 Get(Key),这两个基本操作的时间开销为常数

实验1:测试程序2(6分)

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

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());
al.add(new Integer());
al.add(new Integer());
al.add(new String("hello"));
// First print them out using a for loop.
System.out.println("Retrieving by index:");
for (int i = ; i < al.size(); i++) {
System.out.println("Element " + i + " = " + al.get(i));
}
}
}

运行截图:

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();
while (li.hasNext())
System.out.println(li.next());
if (l.indexOf("Hello") < )
System.err.println("Lookup does not work");
else
System.err.println("Lookup works");
}
}

运行截图:

实验1:测试程序3(6分)

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

掌握ArrayListLinkList两个类的用途及常用API

9-1程序如下:

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)
{
//创建a、b两个链表
var a = new LinkedList();
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");  
  //把b中的单词合并成a

  // merge the words from b into a

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

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

  System.out.println(a);

  // remove every second word from b  
  //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);

  // bulk operation: remove all words in b from a  
  //批量操作:从a中删除b中的所有单词

  a.removeAll(b);

  System.out.println(a);  

}
}

运行截图:

总结:

ArrayList是实现了基于动态数组的数据结构,而LinkedList是基于链表的数据结构

ArrayList类提供了一种可增长数组的实现方式。使用ArrayList的优点在于,对于get和set的调用花费常数时间。其缺点在于新项的插入和现有项的删除代价昂贵,除非在ArrayList的末端实现。

LinkedList提供了一种双链表实现。使用LinkedList的优点在于,新项的插入和现有项的删除。这意味着,在表的前端进行添加和现有项的删除都花费常数时间,由此LinkedList提供了addFirst、removeFirst等方法。LinkedList的缺点是不容易作索引,因此对get的调用很昂贵,除非调用接近表的端点

实验2:测试程序1(6分)

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

import javax.swing.*;
public class SimpleFrameTest
{
public static void main(String[] args)
{
JFrame frame = new JFrame();
frame.setBounds(, ,, );
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}

运行截图:

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

l 掌握空框架创建方法;

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

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

10-1程序如下:

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();//定义了一个子类SimpleFrame
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//定义一个用户关闭框架时的响应动作
frame.setVisible(true);//为了显示框架。main方法调用了框架的setVisble方法
});
}
}

class SimpleFrame extends JFrame
{
private static final int DEFAULT_WIDTH = ;
private static final int DEFAULT_HEIGHT = ;//将构造器框架设置为300×200像素

public SimpleFrame()
{
setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);
}
}

运行截图:

实验2:测试程序2(6分)

l 在elipse IDE中调试运行教材412页程序10-2,结合运行结果理解程序;

掌握确定框架常用属性的设置方法

程序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();//定义了一个子类SimpleFrame
frame.setTitle("SizedFrame");////定义一个用户关闭框架时的响应动作
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);//为了显示框架。main方法调用了框架的setVisble方法
});
}
}

class SizedFrame extends JFrame
{
public SizedFrame()
{
// get screen dimensions获取屏幕尺寸

  Toolkit kit = Toolkit.getDefaultToolkit();//调用一个Toolkit的静态方法getDefauitToolkit得到一个Toolkit对象  
  Dimension screenSize = kit.getScreenSize();//返回屏幕尺寸大小  
  int screenHeight = screenSize.height;  
  int screenWidth = screenSize.width;

  // set frame width, height and let platform pick screen location

  setSize(screenWidth / , screenHeight / );  
  setLocationByPlatform(true);//将窗口大小设置为取值的一半,告知窗口系统定位框架

  // set frame icon//设置新图标

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

}
}

运行截图:

实验2:测试程序3(6分)

l 在elipse IDE中调试运行教材418页程序10-3,结合运行结果理解程序;

l 掌握在框架中添加组件;

l 掌握自定义组件的用法。

程序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(() -> //lambda表达式
{
NotHelloWorldFrame frame = new NotHelloWorldFrame(); //创建一个NotHelloWorldFrame类对象
frame.setTitle("NotHelloWorld"); //通过frame来调用setTitle()方法,来设置标题
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//调用setDefaultCloseOperation()方法取消窗口
frame.setVisible(true); //调用setVisible()方法设置窗口是否可见
});
}
}

/**
* A frame that contains a message panel.
*/
class NotHelloWorldFrame extends JFrame //创建一个NotHelloWorldFrame类来继承JFrame类
{
public NotHelloWorldFrame() //NotHelloWorldFrame构造器
{
add(new NotHelloWorldComponent()); //add()方法添加窗口
pack();
}
}

/**
* A component that displays a message.
*/
class NotHelloWorldComponent extends JComponent //创建一个NotHelloWorldComponent类继承JComponent类
{
public static final int MESSAGE_X = ; //私有属性,常量MESSAGE_X以及MESSAGE_Y 的定义
public static final int MESSAGE_Y = ;

private static final int DEFAULT_WIDTH = ; //私有属性,常量DEFAULT_WIDTH以及DEFAULT_HEIGHT 的定义
private static final int DEFAULT_HEIGHT = ;

public void paintComponent(Graphics g) //paintComponent()方法定义来实现绘图
{
g.drawString("Not a Hello, World program", MESSAGE_X, MESSAGE_Y);
}

public Dimension getPreferredSize() //getPreferredSize()得到维度
{
return new Dimension(DEFAULT_WIDTH, DEFAULT_HEIGHT);
}
}

运行截图:

第三部分:实验总结:(19分)

本周学习了java集合框架,图形程序设计,两章内容,了解特vetor,stack,hashtable三个类的用途,以及arraylist,linklist用途,java集合框架如何创建和一些属性设置,2D图形的绘制,可能知识点太多会消化不了,但是还得通过理解去学习编程,理解代码。经过这几周对于Java面向对象程序设计的学习,让我更加深刻的了解到的面向对象思想的重要性。在这周的课堂上我们加强对之前一些代码的印象,并学习新知识,对之不断的熟悉。Java这门语言对于我们专业来说是十分重要的,所以我们都努力的理解Java编程思想,以及基本技巧,尽量学到更多知识。