java容器
来源:互联网 发布:php怎么写html 编辑:程序博客网 时间:2024/06/06 06:29
容器是用于持有对象的。最好的持有对象的方法是数组,但是数组的长度固定。容器的顶层接口是Collections, 其中包含List,set接口, Map接口不属于Collections接口的。
ArrayList
是动态数组,从类的定义上看,
public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable
有几个特点,支持泛型,
RandomAccess是一个标记接口,接口内没有定义任何内容。
实现了Cloneable接口的类,可以调用Object.clone方法返回该对象的浅拷贝。
通过实现 java.io.Serializable 接口以启用其序列化功能。未实现此接口的类将无法使其任何状态序列化或反序列化。序列化接口没有方法或字段,仅用于标识可序列化的语义。
ArrayList的属性,两个私有属性:
/** * The array buffer into which the elements of the ArrayList are stored. * The capacity of the ArrayList is the length of this array buffer. */ private transient Object[] elementData; /** * The size of the ArrayList (the number of elements it contains). * * @serial */ private int size;
transient是关键字,用来表示一个域不是该对象串行化的一部分。
构造函数有3个
/** * Constructs an empty list with the specified initial capacity. */ public ArrayList(int initialCapacity) { super(); if (initialCapacity < 0) throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity); this.elementData = new Object[initialCapacity]; } /** * Constructs an empty list with an initial capacity of ten. */ public ArrayList() { this(10); } /** * Constructs a list containing the elements of the specified * collection, in the order they are returned by the collection's * iterator. */ public ArrayList(Collection<? extends E> c) { elementData = c.toArray(); size = elementData.length; // c.toArray might (incorrectly) not return Object[] (see 6260652) if (elementData.getClass() != Object[].class) elementData = Arrays.copyOf(elementData, size, Object[].class); }
2:无参数构造函数,默认数组大小是10
3:用一个Collection创建。
添加一个元素:
public boolean add(E e) { ensureCapacity(size + 1); // Increments modCount!! elementData[size++] = e; return true; }
/** * Increases the capacity of this <tt>ArrayList</tt> instance, if * necessary, to ensure that it can hold at least the number of elements * specified by the minimum capacity argument. * * @param minCapacity the desired minimum capacity */ public void ensureCapacity(int minCapacity) { modCount++; int oldCapacity = elementData.length; if (minCapacity > oldCapacity) { Object oldData[] = elementData; int newCapacity = (oldCapacity * 3)/2 + 1; if (newCapacity < minCapacity) newCapacity = minCapacity; // minCapacity is usually close to size, so this is a win: elementData = Arrays.copyOf(elementData, newCapacity); } }
如果超出数组目前的大小,则数组的长度变为原来的*3/2 + 1;
在指定的位置插入元素
public void add(int index, E element) { if (index > size || index < 0) throw new IndexOutOfBoundsException( "Index: "+index+", Size: "+size); ensureCapacity(size+1); // Increments modCount!! System.arraycopy(elementData, index, elementData, index + 1, size - index); elementData[index] = element; size++; }
原理就是把后边的数组都向右移动一位。
取指定位置的元素
public E get(int index) { RangeCheck(index); return (E) elementData[index]; }
移除某个位置的元素
public E remove(int index) { RangeCheck(index); modCount++; E oldValue = (E) elementData[index]; int numMoved = size - index - 1; if (numMoved > 0) System.arraycopy(elementData, index+1, elementData, index, numMoved); elementData[--size] = null; <span style="color:#ff0000;">// Let gc do its work </span> return oldValue; }
LinkedList
底层是双向循环链表,头结点不存放数据
public class LinkedList<E> extends AbstractSequentialList<E> implements List<E>, Deque<E>, Cloneable, java.io.Serializable
LinkedList 是一个继承于AbstractSequentialList的双向链表。它也可以被当作堆栈、队列或双端队列进行操作。
LinkedList 实现 List 接口,能对它进行队列操作。
LinkedList 实现 Deque 接口,即能将LinkedList当作双端队列使用。
LinkedList 实现了Cloneable接口,即覆盖了函数clone(),能克隆。
LinkedList 实现java.io.Serializable接口,这意味着LinkedList支持序列化,能通过序列化去传输。
LinkedList 是非同步的。
还是两个私有属性
1 private transient Entry<E> header = new Entry<E>(null, null, null);2 private transient int size = 0;
1 private static class Entry<E> { 2 E element; 3 Entry<E> next; 4 Entry<E> previous; 5 6 Entry(E element, Entry<E> next, Entry<E> previous) { 7 this.element = element; 8 this.next = next; 9 this.previous = previous;10 }11 }
两个构造方法:
1 public LinkedList() {2 header.next = header.previous = header;3 }4 public LinkedList(Collection<? extends E> c) {5 this();6 addAll(c);7 }
添加元素,add:
// 将元素(E)添加到LinkedList中 public boolean add(E e) { // 将节点(节点数据是e)添加到表头(header)之前。 // 即,将节点添加到双向链表的末端。 addBefore(e, header); return true; } public void add(int index, E element) { addBefore(element, (index==size ? header : entry(index))); } private Entry<E> addBefore(E e, Entry<E> entry) { Entry<E> newEntry = new Entry<E>(e, entry, entry.previous); newEntry.previous.next = newEntry; newEntry.next.previous = newEntry; size++; modCount++; return newEntry; }
删除元素:
逻辑简单,但是个人觉得要先要遍历链表找到这个元素,在删除。
1 private E remove(Entry<E> e) { 2 if (e == header) 3 throw new NoSuchElementException(); 4 // 保留将被移除的节点e的内容 5 E result = e.element; 6 // 将前一节点的next引用赋值为e的下一节点 7 e.previous.next = e.next; 8 // 将e的下一节点的previous赋值为e的上一节点 9 e.next.previous = e.previous;10 // 上面两条语句的执行已经导致了无法在链表中访问到e节点,而下面解除了e节点对前后节点的引用11 e.next = e.previous = null;12 // 将被移除的节点的内容设为null13 e.element = null;14 // 修改size大小15 size--;16 modCount++;17 // 返回移除节点e的内容18 return result;19 }复制代码
获取某个元素,get,remove的时候要调用
// 获取双向链表中指定位置的节点 private Entry<E> entry(int index) { if (index < 0 || index >= size) throw new IndexOutOfBoundsException("Index: "+index+ ", Size: "+size); Entry<E> e = header; // 获取index处的节点。 // 若index < 双向链表长度的1/2,则从前先后查找; // 否则,从后向前查找。 if (index < (size >> 1)) { for (int i = 0; i <= index; i++) e = e.next; } else { for (int i = size; i > index; i--) e = e.previous; } return e; }
若index < size/2;从前往后;若index >= size/2;从后往前。
- Java容器:容器一览
- Java容器
- Java容器
- java容器
- java容器
- Java容器
- java容器
- JAVA容器
- JAVA 容器
- java 容器
- java容器
- java容器
- java容器
- JAVA容器
- java容器
- java 容器
- java容器
- JAVA 容器
- LeetCode-150.Evaluate Reverse Polish Notation
- emWin 2天速成实例教程000_如何快速入门ucGUI/emWin
- 文章标题
- POJ 2195 Going Home(最小权匹配、KM算法)
- The Donkey of Gui Zhou驴和老虎是否相遇问题(hdu4704)
- java容器
- Zabbix3.0 自动邮件报障
- leetcode 171 Excel Sheet Column Number C++
- <canvas>学习笔记——实时绘制线条摆动
- Java泛型
- Unity3d中的属性(Attributes)整理
- 用栈实现两位数表达式的求值
- jQuery选择器—表单选择器
- 海盗分金币