Java 集合的简单实现 (ArrayList & LinkedList & Queue & Stack)
ArrayList
就是数组实现的啦,没什么好说的,如果数组不够了就扩容到原来的1.5倍
实现了迭代器
package com.wenr.collection; import java.io.Serializable;
import java.util.Arrays;
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.RandomAccess; /**
* @author wenr
*
* 实现方法:
* - void add(E e)
* - void add(int index, E e)
* - E get(int index)
* - int indexOf(Object o)
* - boolean contains(Object o)
* - int size()
* - boolean isEmpty()
* - E remove(int index)
* - boolean remove(Object o)
* - Iterator<E> iterator()
*
*/
public class ArrayListDemo<E> implements RandomAccess, Cloneable, Serializable{ private static final int DEFAULT_SIZE = 10; private Object[] elementData;
private int size = 0; ArrayListDemo() {
this(DEFAULT_SIZE);
} ArrayListDemo(int initialCapacity) {
if (initialCapacity < 0) {
throw new IllegalArgumentException("初始化参数错误:" + initialCapacity);
} else {
elementData = new Object[initialCapacity];
}
} public void add(E e) {
isCapacityEnough(size + 1);
elementData[size++] = e;
} public void add(int index, E e) {
rangeCheckForAdd(index);
isCapacityEnough(size + 1);
System.arraycopy(elementData, index, elementData, index + 1, size - index);
elementData[index] = e;
size++;
} private void rangeCheckForAdd(int index) {
if (index < 0 || index > size)
throw new IndexOutOfBoundsException("下标越界:" + index);
} private void isCapacityEnough(int capacity) {
// 溢出
if (capacity < 0)
throw new OutOfMemoryError();
// 需要扩容
if (capacity - elementData.length > 0)
grow(capacity);
} private void grow(int capacity) {
int oldCapacity = elementData.length;
// 设置新容量是原容量的1.5倍
int newCapacity = oldCapacity + (oldCapacity >> 1);
// 可能会有一次加入多个数据的情况 那么久直接加到所需容量
if (capacity - newCapacity > 0)
newCapacity = capacity;
elementData = Arrays.copyOf(elementData, newCapacity);
} public E get(int index) {
rangeCheck(index);
return (E)elementData[index];
} private void rangeCheck(int index) {
if (index < 0 || index >= size)
throw new IllegalArgumentException("下标越界:" + index);
} public int indexOf(Object o) {
if (o == null) {
for (int i = 0; i < size; ++i) {
if (elementData[i] == null)
return i;
}
} else {
for (int i = 0; i < size; ++i) {
if (o.equals(elementData[i]))
return i;
}
}
return -1;
} public boolean contains(Object o) {
return indexOf(o) >= 0;
} public int size() {
return size;
} public boolean isEmpty() {
return size == 0;
} public E remove(int index) {
rangeCheck(index);
E value = (E)elementData[index];
int moveSize = size - index - 1;
if (moveSize > 0)
System.arraycopy(elementData, index + 1, elementData, index, moveSize);
elementData[--size] = null;
return value;
} public boolean remove(Object o) {
int index = indexOf(o);
if (index < 0) {
return false;
} else {
remove(index);
return true;
}
} public Iterator<E> iterator() {
return new Itr();
} private class Itr implements Iterator<E> { int cursor = 0; // 下一个将返回的元素 @Override
public boolean hasNext() {
return cursor != size;
} @Override
public E next() {
if (cursor < 0 || cursor >= size)
throw new NoSuchElementException();
Object[] elementData = ArrayListDemo.this.elementData;
return (E)elementData[cursor++];
} } public static void main(String[] args) {
ArrayListDemo<String> list = new ArrayListDemo<String>();
list.add("1");
list.add("2");
list.add("3");
System.out.println(list.get(0));
System.out.println(list.get(1));
System.out.println(list.get(2));
System.out.println(list.indexOf("3"));
System.out.println(list.remove("3"));
System.out.println(list.contains("3"));
// System.out.println(list.get(3));
Iterator<String> itr = list.iterator();
while (itr.hasNext()) {
System.out.println(itr.next());
}
} }
LinkedList
嗯,就是一个双向链表~
package com.wenr.collection; import java.util.Iterator;
import java.util.NoSuchElementException; /**
* @author wenr
*
* 实现方法:
* - void add(E e)
* - void add(int index, E e)
* - E get(int index)
* - int indexOf(Object o)
* - boolean contains(Object o)
* - E remove(int index)
* - boolean remove(Object o)
* - boolean isEmpty()
* - int size()
* - Iterator<E> iterator()
*
*/
public class LinkedListDemo<E> { private int size;
Node<E> first;
Node<E> last; public LinkedListDemo() {
} // 添加一个节点在结尾处
public void add(E e) {
Node<E> l = last;
Node<E> node = new Node(e, last, null);
last = node;
if (l == null) {
first = node;
} else {
l.next = node;
}
size++;
} public void add(int index, E e) {
rangeCheckForAdd(index);
if (index == size) {
add(e);
} else {
Node<E> x = node(index);
addBeforeNode(e, x);
}
} private void rangeCheckForAdd(int index) {
if (index < 0 || index > size)
throw new IndexOutOfBoundsException("下标越界:" + index);
} private void addBeforeNode(E e, Node<E> beforeNode) {
Node<E> preNode = beforeNode.prev;
Node<E> newNode = new Node(e, preNode, beforeNode);
if (preNode == null) {
first = newNode;
} else {
preNode.next = newNode;
}
beforeNode.prev = newNode;
size++;
} private Node<E> node(int index) {
// 如果node在前一半就正向查找 否则逆向查找
if (index < (size >> 1)) {
Node<E> cursor = first;
for (int i = 0; i < index; ++i) {
cursor = cursor.next;
}
return cursor;
} else {
Node<E> cursor = last;
for (int i = size-1; i > index; --i) {
cursor = cursor.prev;
}
return cursor;
}
} public E get(int index) {
rangeCheck(index);
Node<E> x = node(index);
return x.item;
} private void rangeCheck(int index) {
if (index < 0 || index >= size)
throw new IndexOutOfBoundsException("数组越界:" + index);
} public int indexOf(Object o) {
int index = 0;
if (o == null) {
for (Node<E> x = first; x != null; x = x.next) {
if (x.item == null)
return index;
index++;
}
} else {
for (Node<E> x = first; x != null; x = x.next) {
if (o.equals(x.item))
return index;
index++;
}
}
return -1;
} public E remove(int index) {
rangeCheck(index); Node<E> x = node(index);
final E element = x.item;
final Node<E> prev = x.prev;
final Node<E> next = x.next; if (prev == null) {
first = next;
} else {
prev.next = next;
x.prev = null;
} if (next == null) {
last = prev;
} else {
next.prev = prev;
x.next = null;
} x.item = null;
size--;
return element;
} public boolean remove(Object o) {
int index = indexOf(o);
if (index < 0)
return false;
remove(index);
return true;
} public int size() {
return size;
} public boolean isEmpty() {
return size == 0;
} public boolean contains(Object o) {
return indexOf(o) >= 0;
} public Iterator<E> iterator() {
return new Itr();
} private static class Node<E> {
E item;
Node<E> prev;
Node<E> next;
public Node(E item, Node<E> prev, Node<E> next) {
this.item = item;
this.prev = prev;
this.next = next;
}
} private class Itr implements Iterator<E> { private Node<E> cursor;
private int nextIndex; public Itr() {
cursor = first;
nextIndex = 0;
} @Override
public boolean hasNext() {
return nextIndex < size;
} @Override
public E next() {
if (!hasNext())
throw new NoSuchElementException();
E element = cursor.item;
cursor = cursor.next;
nextIndex++;
return element;
} } public static void main(String[] args) {
LinkedListDemo<String> list = new LinkedListDemo<>();
list.add("aaaa");
list.add("bbbb");
list.add("cccc");
list.add("dddd");
System.out.println(list.size());
System.out.println(list.get(1));
System.out.println(list.get(2));
System.out.println(list.get(0));
System.out.println(list.remove(2));
list.add(3, "eeee");
System.out.println(list.get(1));
System.out.println(list.get(2));
System.out.println(list.get(3));
System.out.println("_____");
Iterator<String> itr = list.iterator();
while (itr.hasNext()) {
System.out.println(itr.next());
}
} }
Queue
瞎写的啦哈哈哈
队列先进先出 用循环队列实现 节省空间
当front==tail就是队列为空
因为如果队列全部装满的时候front==tail,和空一样,所以循环队列不能全部装满,至少空出一位
当(tail+1)%capacity==front的时候就是队列满(capacity是队列容量大小
package com.wenr.collection; import java.util.Arrays;
import java.util.NoSuchElementException; /**
*
* @author wenr
*
* 通过数组实现的循环队列
*
* 实现方法:
* - boolean offer(E)
* - boolean isEmpty()
* - E peek()
* - E poll()
* - int size()
*
*/ public class QueueDemo<E> { private static final int DEFAULT_SIZE = 0; private Object[] elementData;
private int front;
private int tail; public QueueDemo() {
this(DEFAULT_SIZE);
} public QueueDemo(int capacity) {
elementData = new Object[capacity];
front = tail = 0;
} // 向队列中加入一个元素
public boolean offer(E element) {
int capacity = elementData.length;
// 注意这里是capacity-1哦 因为要区别empty 所以循环队列不能装满的
if (size() == capacity - 1) {
grow(++capacity);
}
elementData[tail] = element;
tail = (tail + 1) % capacity;
return true;
} // 获取并移除此队列的头
public E poll() {
if (isEmpty())
throw new NoSuchElementException();
E element = (E)elementData[front];
front = (front + 1) % elementData.length;
return element;
} private void grow(int capacity) {
if (capacity == -1)
throw new OutOfMemoryError(); int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1);
if (newCapacity < capacity)
newCapacity = capacity;
if (front < tail) {
// [front...tail]
elementData = Arrays.copyOf(elementData, newCapacity);
} else {
// [...tail front...]
Object[] tempData = new Object[newCapacity];
int moveSize = oldCapacity - front;
System.arraycopy(elementData, front, tempData, 0, moveSize);
System.arraycopy(elementData, 0, tempData, moveSize, tail);
elementData = tempData;
tempData = null;
front = 0;
tail = oldCapacity - 1;
} } // 获取但不移除此队列的头
public E peek() {
if (isEmpty())
throw new NoSuchElementException();
else
return (E)elementData[front];
} public boolean isEmpty() {
return front == tail;
} public int size() {
int capacity = elementData.length;
return (tail - front + capacity) % capacity;
} public static void main(String[] args) {
QueueDemo<Integer> q = new QueueDemo<>(5);
q.offer(1);
q.offer(2);
q.offer(3);
q.offer(4);
System.out.println(q.poll());
System.out.println(q.poll());
q.offer(5);
q.offer(6);
q.offer(7);
q.offer(8);
while (!q.isEmpty()) {
System.out.print(q.peek() + " ");
q.poll();
}
//q.poll();
}
}
Stack
哦 还是瞎写的
栈 先进后出 没什么好说的 都比较简单
package com.wenr.collection; import java.util.Arrays;
import java.util.NoSuchElementException;
import java.util.Stack; /**
* @author wenr
*
* 实现函数:
* - E peek()
* - E pop()
* - void push(E)
* - isEmpty()
* - size()
*
*/
public class StackDemo<E> {
private static final int DEFAULT_SIZE = 10;
private int top;
private Object[] data; public StackDemo() {
this(DEFAULT_SIZE);
} public StackDemo(int capacity) {
data = new Object[capacity];
} public E peek() {
if (isEmpty())
throw new NoSuchElementException();
return (E)data[top - 1];
} public E pop() {
if (isEmpty())
throw new NoSuchElementException();
return (E)data[--top];
} public void push(E e) {
int capacity = data.length;
if (top == capacity) {
grow(capacity + 1);
}
data[top++] = e;
} private void grow(int capacity) {
if (capacity <= 0)
throw new OutOfMemoryError();
int oldCapacity = data.length;
int newCapacity = oldCapacity + (oldCapacity >> 1);
if (newCapacity < capacity) {
newCapacity = capacity;
}
data = Arrays.copyOf(data, newCapacity);
} public boolean isEmpty() {
return top == 0;
} public int size() {
return top;
} public static void main(String[] args) {
StackDemo<Integer> stack = new StackDemo<>(3);
stack.push(1);
stack.push(2);
stack.push(3);
stack.push(4);
stack.push(5);
stack.push(6);
stack.pop();
stack.push(7);
while (!stack.isEmpty()) {
System.out.println(stack.peek());
stack.pop();
}
} }
Java 集合的简单实现 (ArrayList & LinkedList & Queue & Stack)的更多相关文章
- Java 集合系列 07 List总结(LinkedList, ArrayList等使用场景和性能分析)
java 集合系列目录: Java 集合系列 01 总体框架 Java 集合系列 02 Collection架构 Java 集合系列 03 ArrayList详细介绍(源码解析)和使用示例 Java ...
- java集合的实现细节--ArrayList和LinkedList
ArrayList和LinkedList的实现差异 List代表一种线性表的数据结构,ArrayList则是一种顺序存储的线性表,ArrayList底层采用动态数组的形式保存每一个集合元素,Link ...
- Java集合系列(二):ArrayList、LinkedList、Vector的使用方法及区别
本篇博客主要讲解List接口的三个实现类ArrayList.LinkedList.Vector的使用方法以及三者之间的区别. 1. ArrayList使用 ArrayList是List接口最常用的实现 ...
- java集合的简单用法
typora-root-url: iamge [TOC] 1.集合接口 1.1将集合的接口与实现分离 与现代的数据结构类库的常见情况一样,Java集合类库也将接口(interface)与实现(im ...
- 【Java集合源代码剖析】ArrayList源代码剖析
版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/mmc_maodun/article/details/35568011 转载请注明出处:http:// ...
- Java总结 - List实现类ArrayList&LinkedList
本文是根据源码进行学习的,如果我有什么理解不对的地方请多指正,谢谢您 上面基本就是List集合类的类图关系了,图中省略掉了比如Cloneable等标记接口,那么List分别具体的主要实现类有:Arra ...
- jdk集合常用方法分析之ArrayList&LinkedList&以及两者的对比分析
集合使用注意事项: 1.集合当中只能放置对象的引用,无法放置原生数据类型,我们需要使用原生数据类型的包装类才能加入到集合当中去(JDK5之后会进行自动的装箱和拆箱操作,表面上看集合中是可以直接放置原生 ...
- Java 集合:HashSet 与 ArrayList
Set 集合是无序不可以重复的的.List 集合是有序可以重复的. Java 集合:HashSet 与 hashCode.equals 博客里面已经说到这个问题,但是解释的还是不够清楚. 看一个小例子 ...
- Java 集合框架(三)—— LinkedList
三.链表 —— LinkedList ArrayList 虽然好用,但是数组和数组列表都有一个重大的缺陷:从数组的中间位置删除一个元素要付出很大的代价,其原因是数组中处于被删除元素之后的所有元素都要向 ...
随机推荐
- Core Data使用之一(Swift): 获取
//获取entity中的数据 func fetchFiles() { //第一步,获取总代理 let appDelegate = UIApplication.sharedApplication().d ...
- 段落p元素内的响应式文本布局就靠rem单位实现
<!DOCTYPE html><html><head lang="en"> <meta charset="UTF-8&qu ...
- 对js原型对象的拓展和原型对象的重指向的区别的研究
我写了如下两段代码: function Person(){} var p1 = new Person(); Person.prototype = { constructor: Person, name ...
- WEB 开发者应该具备的 6 大技能?
1. 界面和用户体验 注意,浏览器的实现标准是不一致的,请确保你的网站能够兼容所有主流的浏览器.最少需要测试的有 Gecko 引擎 (Firefox),WebKit引擎(Safari以及一些手机浏览器 ...
- PHP文件夹文件拷贝/复制函数 dir_copy($src = '', $dst = '')
/* * 文件夹文件拷贝 * * @param string $src 来源文件夹 * @param string $dst 目的地文件夹 * @return bool */ function dir ...
- linux下两台服务器文件实时同步方案设计和实现
inux下两台服务器文件实时同步方案设计和实现 假设有如下需求: 假设两个服务器: 192.168.0.1 源服务器 有目录 /opt/test/ 192.168.0.2 目标服务器 有目录 /o ...
- MyEclipse 中 添加 js自动完成模版
MyEclipse 中 添加 js自动完成模版: window>preference>MyEclipse>Files and Editors>JavaScript>Edi ...
- 用反射技术替换工厂种的switch分支(14)
首先给大家拜个晚年,祝大家新春快乐,万事如意,鸡年大吉. 好了,前面我们讲了很多的工厂模式,其中,有个很明显的特点,工厂中,有一个方法,里面有很多的swich case 分支,我们前面说过,我们可以 ...
- 《JAVASCRIPT高级程序设计》window/location/navigator/screen/history对象
如果要在web中使用JAVASCRIPT,那么BOM(浏览器对象模型)毫无疑问是最重要的部分.BOM提供了很多对象,例如,window.location.navigator.screen.histor ...
- haproxy学习
1.安装 # wget http://haproxy.1wt.eu/download/1.3/src/haproxy-1.3.20.tar.gz # tar zcvf haproxy-1.3.20.t ...