zoukankan      html  css  js  c++  java
  • Java 集合:(八) Vector 子类 Stack

    一、Stack 概述

      1、Stack 是栈结构,它继承与 Vector。它的特性是:先进后出(FILO,First In Last Out)或 后进先出(LIFO,Last In First Out);

      2、Stack是Vector的子类,比Vector多了几个方法,它的后进先出的特征,就是通过调用这几个方法实现的。

      3、

      4、

      5、

    二、Stack 结构

      1、Stack 类声明

    public class Stack<E> extends Vector<E>
    

        可以发现 Stack 是 Vector 的子类。

      2、Stack 类继承结构

        

      3、

      4、

    三、Stack 创建

      1、构造器

        源码:

    1 public Stack() {}

        Stack 只提供了一个无参的构造器,但是这里会调用父类的构造器:

    1 public Vector() {
    2     this(10);
    3 }

        可以发现,在这里创建了一个长度为10的数组。

      2、添加元素

        通过 Stack 的 push() 方法,可以向栈中添加元素,本质还是调用父类 Vector 的 addElement() 方法:

    1 public synchronized void addElement(E obj) {
    2      modCount++;
    3      ensureCapacityHelper(elementCount + 1);
    4      elementData[elementCount++] = obj;
    5 }

        可以发现,如果需要进行扩容的话也是调用 vector 中的扩容方式来扩容的,即容量扩容为原来的2倍。

      3、

    四、Stack 方法

      1、方法列表

        

      2、push(E) 方法

        把元素压入栈顶,等价于add(item),这里为了更形象化,单独设计了一个push。

        源码:

     1     public E push(E item) {
     2         addElement(item);
     3 
     4         return item;
     5     }
     6     // 调用 Vector 的 addElement() 方法
     7     public synchronized void addElement(E obj) {
     8         modCount++;
     9         ensureCapacityHelper(elementCount + 1);
    10         elementData[elementCount++] = obj;
    11     }

         在JDK9 中:

        

         然后调用 Vector 中的 add 方法:

        

      3、pop() 方法:弹出栈顶元素

        源码:

     1 public synchronized E pop() {
     2     E       obj;
     3     int     len = size();
     4 
     5     obj = peek();
     6     removeElementAt(len - 1);
     7 
     8     return obj;
     9 }
    10 
    11 // 调用 Vector 的removeElementAt()方法
    12 public synchronized void removeElementAt(int index) {
    13     modCount++;
    14     if (index >= elementCount) {
    15         throw new ArrayIndexOutOfBoundsException(index + " >= " +
    16                                                  elementCount);
    17     }
    18     else if (index < 0) {
    19         throw new ArrayIndexOutOfBoundsException(index);
    20     }
    21     int j = elementCount - index - 1;
    22     if (j > 0) {
    23         System.arraycopy(elementData, index + 1, elementData, index, j);
    24     }
    25     elementCount--;
    26     elementData[elementCount] = null; /* to let gc do its work */
    27 }

      4、peek() 方法:获取栈顶元素,不移除

        源码:

     1 public synchronized E peek() {
     2     int     len = size();
     3 
     4     if (len == 0)
     5         throw new EmptyStackException();
     6     return elementAt(len - 1);
     7 }
     8 
     9 public synchronized E elementAt(int index) {
    10     if (index >= elementCount) {
    11         throw new ArrayIndexOutOfBoundsException(index + " >= " + elementCount);
    12     }
    13 
    14     return elementData(index);
    15 }
    16 
    17 E elementData(int index) {
    18     return (E) elementData[index];
    19 }

      5、empty() 方法

        源码:

    1 public boolean empty() {
    2     return size() == 0;
    3 }

      6、search(Object) 方法:返回的是从栈顶开始计算索引位置的

        源码:

     1 public synchronized int search(Object o) {
     2     int i = lastIndexOf(o);
     3 
     4     if (i >= 0) {
     5         return size() - i;
     6     }
     7     return -1;
     8 }
     9 
    10 public synchronized int lastIndexOf(Object o) {
    11     return lastIndexOf(o, elementCount-1);
    12 }
    13 
    14 public synchronized int lastIndexOf(Object o, int index) {
    15     if (index >= elementCount)
    16         throw new IndexOutOfBoundsException(index + " >= "+ elementCount);
    17 
    18     if (o == null) {
    19         for (int i = index; i >= 0; i--)
    20             if (elementData[i]==null)
    21                 return i;
    22     } else {
    23         for (int i = index; i >= 0; i--)
    24             if (o.equals(elementData[i]))
    25                 return i;
    26     }
    27     return -1;
    28 }

    五、案例

      1、数组模拟栈一

     1 class ArrayStack {
     2     private int[] data;   //存储数据
     3     private int size;    //元素的个数
     4 
     5     //默认容量
     6     private static final int DEFAULT_CAPACITY = 10;
     7 
     8     ArrayStack() {
     9         data = new int[DEFAULT_CAPACITY];
    10     }
    11 
    12     ArrayStack(int capacity) {
    13         data = new int[capacity];
    14     }
    15 
    16     //把item压入堆栈顶部
    17     public void push(int ele) {
    18         //判断是否需要扩容
    19         if (size > data.length) {
    20             data = Arrays.copyOf(data, data.length * 2);
    21         }
    22         data[size++] = ele;
    23     }
    24 
    25     //查看堆栈顶部的对象,但不从堆栈中移除它
    26     public int peek() {
    27         if (size == 0) {
    28             throw new EmptyStackException();
    29         }
    30         return data[size-1];  //获取栈顶元素
    31     }
    32 
    33     //移除堆栈顶部的对象,并作为此函数的值返回该对象
    34     public int pop() {
    35         int o = this.peek();       //获取栈顶元素
    36         size--;                    //减少元素个数
    37         return o;
    38     }
    39 
    40     //返回对象在栈中的位置,以 1 为基数,从栈顶开始计算
    41     public int search(int ele) {
    42         //顺着放倒着拿(FILO/LIFO)
    43         for (int i = size - 1; i >=0; i--)
    44         {
    45             if (ele == data[i]) {
    46                 return size - i;
    47             }
    48         }
    49         return -1;    //返回栈中不存在该元素
    50     }
    51 
    52     public int size() {
    53         return size;
    54     }
    55 
    56     //测试堆栈是否为空
    57     public boolean empty() {
    58         return size == 0;
    59     }
    60 }

      2、数组模拟栈二

     1 /**
     2  *  定义一个ArrayStack 表示栈
     3  */
     4 public class MyArrayStack {
     5     private int maxSize;    // 栈的大小
     6     private int[] stack;    // 数组,数组模拟栈,数据就在该数组中
     7     private int top = -1;   // top 表示栈顶,初始化为 -1
     8 
     9     // 构造器
    10     public MyArrayStack(int maxSize) {
    11         this.maxSize = maxSize;
    12         stack = new int[this.maxSize];
    13     }
    14 
    15     // 判断栈满
    16     public boolean isFull() {
    17         return top == maxSize - 1;
    18     }
    19 
    20     // 判断栈空
    21     public boolean isEmpty() {
    22         return top == -1;
    23     }
    24 
    25     // 入栈 - push
    26     public void push(int value) {
    27         // 先判断栈是否满
    28         if (isFull()) {
    29             System.out.println("栈满");
    30             return;
    31         }
    32         top++;
    33         stack[top] = value;
    34     }
    35 
    36     // 出栈 - pop,将栈顶的数据返回
    37     public int pop() {
    38         // 先判断栈是否空
    39         if (isEmpty()) {
    40             // 抛出异常来处理
    41             throw new RuntimeException("栈空,没有数据··");
    42         }
    43         int value = stack[top];
    44         top--;
    45         return value;
    46     }
    47 
    48     // 显示栈的情况[遍历栈],从栈顶往下显示数据
    49     public void list() {
    50         if (isEmpty()) {
    51             System.out.println("栈空,没有数据~~");
    52             return;
    53         }
    54 
    55         for (int i = top; i >= 0; i--) {
    56             System.out.printf("stack[%d]=%d
    ", i, stack[i]);
    57         }
    58     }
    59 }

     

  • 相关阅读:
    java 接口和抽象类的一个最大的区别
    python 简化数据结构的初始化二 支持关键字参数
    python 简化数据结构的初始化一
    python @staticmethod
    python @classmethod
    codeskulptor hosts
    An Introduction to Interactive Programming in Python (Part 1) -- Week 2_2 练习
    An Introduction to Interactive Programming in Python (Part 1) -- Week 2_1 练习
    mysql-5.7.14-winx64免安装版在win10下的详细配置过程
    python 反模式
  • 原文地址:https://www.cnblogs.com/niujifei/p/14675837.html
Copyright © 2011-2022 走看看