栈
特点:先进后出
栈是限制线性表中元素的插入和删除,只能在线性表的同一端进行的一种特殊线性表,允许插入和删除的一端为变化端,称为栈顶,另一端固定一端,称为栈底。
stack.java
public class Stack {
//定义数组
private int[] arr;
//栈的大小
private int maxSize;
//表示栈顶
private int top = -1;
//初始化
public Stack(int maxSize) {
//加了this的是对象属性 不加的是参数
this.maxSize = maxSize;
this.arr = new int[this.maxSize];
}
//栈满
public boolean isFull() {
return top == maxSize-1;
}
//栈空
public boolean isEmpty() {
return top == -1;
}
//入栈
public void push(int num) {
if(isFull()) {
System.out.println("栈满考虑扩容");
return;
}
top++;
arr[top]=num;
}
//出栈
public int pop() {
if(isEmpty()) {
throw new RuntimeException("栈空没有数据");
}
int res = arr[top];
top--;
return res;
}
//显示栈,从栈顶开始显示元素
public void list() {
if(isEmpty()) {
throw new RuntimeException("栈空没有数据");
}
for(int i = top;i>=0;i--) {
System.out.println("stack["+i+"]="+arr[i]);
}
}
}
TestStack.java
public class TestStack {
public static void main(String[] args) {
//创建一个栈
Stack stack = new Stack(5);
//初始化
String key = "";
Scanner sc = new Scanner(System.in);
boolean loop = true;
while(loop) {
System.out.println("show:表示显示栈");
System.out.println("push:表示入栈");
System.out.println("pop:表示出栈");
System.out.println("quit:表示退出");
key = sc.next();
switch (key) {
case "show":
try {
stack.list();
}catch(Exception e) {
System.out.println(e.getMessage());
}
break;
case "push":
System.out.println("请输入一个数");
int value = sc.nextInt();
stack.push(value);
break;
case "pop":
try {
int res = stack.pop();
System.out.println("出栈的数据是"+res);
}catch(Exception e) {
System.out.println(e.getMessage());
}
break;
case "quit":
loop = false;
break;
}
}
System.out.println("程序退出");
}
}
队列
特点:先进先出
队列使用数组来实现,因为队列的出队,入队时分别冲头、尾来处理的,因此需要两个变量front和rear
front会随着数据的出队而变化,而rear会随着入队而变化
如果尾指针rear小于maxSize-1,就可以向后移动,然后把数据存在当前rear指向的数组元素上
当rear == maxSize-1队列满
当front == rear 队空
Queue.java
public class Queue {
//定义数组
private int[] arr;
//栈的大小
private int maxSize;
//表示队列头
private int front = -1;
//表示队列头
private int rear = -1;
//初始化
public Queue(int maxSize) {
this.maxSize = maxSize;
this.arr = new int[this.maxSize];
}
//队满
public boolean isFull() {
return rear == maxSize-1;
}
//队空
public boolean isEmpty() {
return rear == front;
}
//入队
public void add(int value) {
if(isFull()) {
System.out.println("队满考虑扩容");
return;
}
rear++;
arr[rear]=value;
}
//出队
public int remove() {
if(isFull()) {
System.out.println("队空没有数据");
}
front++;
return arr[front];
}
//显示队列
public void list() {
if(isEmpty()) {
throw new RuntimeException("队空,没有数据");
}
for(int i=front+1;i<=rear;i++) {
System.out.println("queue["+i+"]="+arr[i]);
}
}
}
QueueTest.java
public class Queue {
//定义数组
private int[] arr;
//栈的大小
private int maxSize;
//表示队列头
private int front = -1;
//表示队列头
private int rear = -1;
//初始化
public Queue(int maxSize) {
this.maxSize = maxSize;
this.arr = new int[this.maxSize];
}
//队满
public boolean isFull() {
return rear == maxSize-1;
}
//队空
public boolean isEmpty() {
return rear == front;
}
//入队
public void add(int value) {
if(isFull()) {
System.out.println("队满考虑扩容");
return;
}
rear++;
arr[rear]=value;
}
//出队
public int remove() {
if(isFull()) {
System.out.println("队空没有数据");
}
front++;
return arr[front];
}
//显示队列
public void list() {
if(isEmpty()) {
throw new RuntimeException("队空,没有数据");
}
for(int i=front+1;i<=rear;i++) {
System.out.println("queue["+i+"]="+arr[i]);
}
}
}
泛型
泛型类的定义语法:
class 类名 <泛型标识,...,泛型标识>{
private 泛型标识 变量名;
...
}
泛型类的使用语法:
类名<具体的数据类型> 对象名 = new 类名<具体的数据类型>()
jdk1.7之后,后边的<>可以省略不写
类名<具体的数据类型> 对象名 = new 类名<>()
泛型总结:
类型参数化,让类的定义更加通用
泛型不支持基本数据类型,因为在编译时T编译成Object,基本类型无法转换成Object
泛型类在创建对象的时候,如果没有指定具体数据类型,将按照Object类型来操作
同一泛型类在逻辑上可以看成是多个不同的类型,但实际是相同类型
从泛型类派生子类:
子类也是泛型,子类和父类的泛型要保持一致如果子类不是泛型,那父类要明确泛型类型
保持一致
泛型接口:
泛型接口语法定义:interface 接口名 <泛型标识1,泛型标识2>{
泛型标识 方法名();
...
}实现类也是泛型,实现类和接口的泛型要保持一致,如果接口没有指明类型,则按照Object类型处理
实现类不是泛型,接口要明确泛型类型的数据类型,如果接口没有指明类型,则按照Object类型处理