List:
- 特点:有序 不唯一(可重复)
ArrayList 线性表中的顺序表
- 在内存中分配连续的空间,实现了长度可变的数组•
- 优点:遍历元素和随机访问元素的效率比较高
- 缺点:添加和删除需大量移动元素效率低,按照内容查询效率低。
-
0 1 2 aaa bbb ccc -
代码实现
package cn.bjsxt.collection;
/**
* 自己实现一个ArrayList,帮助我们更好的理解ArrayList类的底层结构!
*
*/
public class SxtArrayList /*implements List*/ {
private Object[] elementData;
private int size;
public int size(){
return size;
}
public boolean isEmpty(){
return size==0;
}
public SxtArrayList(){
this(10);
}
public SxtArrayList(int initialCapacity){
if(initialCapacity<0){
try {
throw new Exception();
} catch (Exception e) {
e.printStackTrace();
}
}
elementData = new Object[initialCapacity];
}
public void add(Object obj){
//数组扩容和数据的拷贝
if(size==elementData.length){
Object[] newArray = new Object[size*2+1];
System.arraycopy(elementData, 0, newArray, 0, elementData.length);
// for(int i=0;i<elementData.length;i++){
// newArray[i] = elementData[i];
// }
elementData = newArray;
}
elementData[size++]=obj;
// size++;
}
public Object get(int index){
rangeCheck(index);
return elementData[index];
}
public void remove(int index){
rangeCheck(index);
//删除指定位置的对象
//a b d e
int numMoved = size - index - 1;
if (numMoved > 0){
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
}
elementData[--size] = null; // Let gc do its work
}
public void remove(Object obj){
for(int i=0;i<size;i++){
if(get(i).equals(obj)){ //注意:底层调用的equals方法而不是==.
remove(i);
}
}
}
public Object set(int index,Object obj){
rangeCheck(index);
Object oldValue = elementData[index];
elementData[index] = obj;
return oldValue;
}
public void add(int index, E element) {
rangeCheckForAdd(index);
ensureCapacityInternal(size + 1); // Increments modCount!!
System.arraycopy(elementData, index, elementData, index + 1,
size - index);
elementData[index] = element;
size++;
}
public void add(int index,Object obj){
rangeCheck(index);
ensureCapacity(); //数组扩容
System.arraycopy(elementData, index, elementData, index + 1,
size - index);
elementData[index] = obj;
size++;
}
private void ensureCapacity(){
//数组扩容和数据的拷贝
if(size==elementData.length){
Object[] newArray = new Object[size*2+1];
System.arraycopy(elementData, 0, newArray, 0, elementData.length);
// for(int i=0;i<elementData.length;i++){
// newArray[i] = elementData[i];
// }
elementData = newArray;
}
}
private void rangeCheck(int index){
if(index<0||index>=size){
try {
throw new Exception();
} catch (Exception e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
SxtArrayList list = new SxtArrayList(3);
list.add("333");
list.add("444");
list.add("5");
list.add("344433");
list.add("333");
list.add("333");
System.out.println(list.size());
// System.out.println(list.get(6));
list.remove("444");
System.out.println(list.size());
}
}
LinkedList 线性表中双向链表
-
采用双向链表存储方式
-
缺点:遍历和随机访问元素效率低下
-
优点:插入、删除元素效率比较高(但是前提也是必须先低效率查询才可。如果插入删除发 生在头尾可以减少查询次数)
-
代码实现
//节点类的描述
package cn.bjsxt.collection;
//用来表示一个节点
public class Node {
Node previous; //上一个节点
Object obj;
Node next; //下一个节点
public Node() {
}
public Node(Node previous, Object obj, Node next) {
super();
this.previous = previous;
this.obj = obj;
this.next = next;
}
public Node getPrevious() {
return previous;
}
public void setPrevious(Node previous) {
this.previous = previous;
}
public Object getObj() {
return obj;
}
public void setObj(Object obj) {
this.obj = obj;
}
public Node getNext() {
return next;
}
public void setNext(Node next) {
this.next = next;
}
}
//线性链表
package cn.bjsxt.collection;
import java.util.LinkedList;
public class SxtLinkedList /*implements List*/ {
private Node first;
private Node last;
private int size;
public void add(Object obj){
Node n = new Node();
if(first==null){
n.setPrevious(null);
n.setObj(obj);
n.setNext(null);
first = n;
last = n;
}else{
//直接往last节点后增加新的节点
n.setPrevious(last);
n.setObj(obj);
n.setNext(null);
last.setNext(n);
last = n;
}
size++;
}
public int size(){
return size;
}
private void rangeCheck(int index){
if(index<0||index>=size){
try {
throw new Exception();
} catch (Exception e) {
e.printStackTrace();
}
}
}
public Object get(int index){ //2
rangeCheck(index);
// 0 1 2 3 4
Node temp = node(index);
if(temp!=null){
return temp.obj;
}
return null;
}
public Node node(int index){
Node temp = null;
if(first!=null){
if (index < (size >> 1)) {
temp = first;
for(int i=0;i<index;i++){
temp = temp.next;
}
}else{
temp = last;
for (int i = size - 1; i > index; i--){
temp = temp.previous;
}
}
}
// LinkedList l;
return temp;
}
public void remove(int index){
Node temp = node(index);
if(temp!=null){
Node up = temp.previous;
Node down = temp.next;
up.next = down;
down.previous = up;
size--;
}
}
public void add(int index,Object obj){
Node temp = node(index);
Node newNode = new Node();
newNode.obj = obj;
if(temp!=null){
Node up = temp.previous;
up.next = newNode;
newNode.previous = up;
newNode.next = temp;
temp.previous = newNode;
size++;
}
}
public static void main(String[] args) {
SxtLinkedList list = new SxtLinkedList();
list.add("aaa");
list.add("bbb");
// list.add(1,"BBBB");
list.add("ccc");
list.add("ddd");
list.add("eee");
// list.remove(1);
System.out.println(list.get(3));
}
}
List常用方法
- List相对Collection增加了关于位置操作的方法
List的遍历方法
- for
- for-each
- Iterator迭代器
理解面向接口编程
- List list = new ArrayList();
- ArrayList list = new ArrayList();
集合中内容是否相同
- 通过equals进行内容比较,而是==引用比较