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

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

运行截图如下:

 

 

 

 

 

 总结:

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(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));
        }
     }
}

运行截图:

 

 

 

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");
   }
}

运行截图:

 

 

 

实验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<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"); //把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(0, 0,300, 200);
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
     frame.setVisible(true);    
   }
}
 

运行截图:

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

掌握空框架创建方法;

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

掌握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 = 300;
   private static final int DEFAULT_HEIGHT = 200;//将构造器框架设置为300×200像素

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

 

运行截图:

 

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

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 / 2, screenHeight / 2);
      setLocationByPlatform(true);//将窗口大小设置为取值的一半,告知窗口系统定位框架

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

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

 运行截图:

 

 

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

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

掌握在框架中添加组件;

掌握自定义组件的用法。

程序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 = 75;     //私有属性,常量MESSAGE_X以及MESSAGE_Y 的定义
   public static final int MESSAGE_Y = 100;
 
   private static final int DEFAULT_WIDTH = 300;  //私有属性,常量DEFAULT_WIDTH以及DEFAULT_HEIGHT 的定义
   private static final int DEFAULT_HEIGHT = 200;
 
   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编程思想,以及基本技巧,尽量学到更多知识。
posted on 2019-11-18 18:19  杨丽霞  阅读(269)  评论(1编辑  收藏  举报