容器List
1.特点:元素可重复,无序---允许有空元素
2.子类:ArrayList,LinkedList,vector
ArrayList:---线程不安全(非同步),效率高, 随着元素的增加而动态扩容
在内存中分配连续的空间,实现了长度可变的数组
优点:遍历元素和随机访问元素的效率比较高
缺点:添加元素和删除元素需要移动元素效率低,按照内容查询效率低
LinkedList:---线程不安全(非同步),效率高, 随着元素的增加不断向链表的后端增加节点
采用双向链表存储方式
优点:插入,删除元素效率比较高(但是前提也是必须先低效率的查询才可,如果插入删除发生在头尾可以减少查询次数)
缺点:遍历和随机访问元素效率低下
vector:---线程安全(同步),效率低
底层实现结构为数组,查询快,增删
List,ArrayList,LinkedList中的方法不在一一介绍,与collection介绍的方法一样使用,使用时可以查找API
对ArrayList底层源码的仿写
package cn.sxt.mycollection;
import java.util.ArrayList;
import javax.management.RuntimeErrorException;
/**
* 增加remove
* @author 123
*
*/
public class SxtArrayList05<E> {
private Object[] elementData;
private int size;
private static final int DEFALT_CAPACITY = 10 ;
public SxtArrayList05(){
elementData = new Object[DEFALT_CAPACITY];
}
public SxtArrayList05(int capacity) {
if(capacity<0){
throw new RuntimeException("容器的容量不能为负数");
} else if(capacity==0){
elementData = new Object[DEFALT_CAPACITY];
}else{
elementData = new Object[capacity];
}
}
public int size(){
return size;
}
public boolean isEmpty(){
return size==0?true:false;
}
public void add(E element){
//什么时候扩容??
if(size == elementData.length){
//扩容操作
Object[] newArray = new Object[elementData.length+(elementData.length>>1)]; //10-->10+10/2
System.arraycopy(elementData, 0, newArray, 0, elementData.length);
elementData = newArray;
}
elementData[size++] = element;
}
public E get(int index) {
checkRange(index);
return (E)elementData[index];
}
public void set(E element, int index) {
checkRange(index);
elementData[index] = element;
}
public void checkRange(int index ){
//索引合法判断 [0,size) 10 0-9
if(index<0||index>size-1){
//不合法
throw new RuntimeException("索引不合法:"+index);
}
}
public void remove(E element){
//element,将它和所有元素挨个比较,获得第一个比较为true的,返回。
for(int i=0;i<size;i++){
if(element.equals(get(i))){ //容器中所有的比较操作,都是用的equals而不是==
//将该元素从此处移除
remove(i);
}
}
}
public void remove(int index){
//a,b,c,d,e,f,g,h
//a,b,c,e,f,g,h,h
int numMoved = elementData.length-index-1;
if(numMoved>0){
System.arraycopy(elementData, index+1, elementData, index, numMoved);
}
elementData[--size] = null;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
//[a,b,c]
sb.append("[");
for(int i=0;i<size;i++){
sb.append(elementData[i]+",");
}
sb.setCharAt(sb.length()-1, ']');
return sb.toString();
}
public static void main(String[] args) {
SxtArrayList05 s1 = new SxtArrayList05();
for(int i=0;i<40;i++){
s1.add("gao"+i);
}
s1.set("dddd", 10);
System.out.println(s1);
System.out.println(s1.get(39));
s1.remove(3);
s1.remove("gao11");
System.out.println(s1);
System.out.println(s1.size);
System.out.println(s1.isEmpty());
}
}
LinkedList底层源码的仿写
package com.datastures.linkedlist;
import javax.xml.transform.Templates;
public class LikedListTest {
private Node first; //第一个节点
private Node last; //最后一个节点
private static int size;
/*
* 加入元素方法
* a,b,c
*/
public void add(Object obj){
Node node = new Node(obj);
if(first == null){ //是否是链表中的第一个元素
first = node;
last = node;
}else{
node.previous = last; //第二个节点
node.next = null;
last.next = node;
last = node; //相当于前面的节点的next指向当前的节点,当前节点的previous指向前一个节点的last
}
size++;
}
/*
* 在指定地点加入元素
*/
public void add(int index,Object obj){
Node node = new Node(obj); //建立新的节点
Node tmp = getNode(index); //取到当前位置节点
if(tmp!=null && (index > 0 && index <= size - 1)){
Node up = tmp.previous;
node.previous = up;
up.next = node;
node.next = tmp;
tmp.previous = node;
}
if(index == 0 && tmp!=null){
tmp.previous = node;
node.next = tmp;
first = node;
}
if(index == size -1 && tmp!=null){
tmp.next = node;
node.previous = tmp;
node.next = null;
last = node;
}
size++;
}
/*
* 重写toString
*/
public String toString(){
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("[");
Node tmp = first;
while (tmp != null) {
stringBuilder.append(tmp.element + ",");
tmp = tmp.next;
}
stringBuilder.setCharAt(stringBuilder.length() - 1,']');
return stringBuilder.toString();
}
/*
* 根据下标求出值
*/
public Object get(int index){
if(index < 0 || index > size - 1){
throw new RuntimeException("索引数组不合法" + index);
}
Node tmp = getNode(index);
return tmp!=null?tmp.element:null;
}
/*
* 得到某个节点
*/
public Node getNode(int index){
Node tmp = null;
if(index > (size >> 1)){
tmp = first;
for (int i = 0; i < index; i++) {
tmp = tmp.next;
}
}else {
tmp = last;
for (int i = size - 1; i >index; i--) {
tmp = tmp.previous;
}
}
return tmp;
}
/*
* 删除某个节点
*/
public void remove(int index){
Node tmp = getNode(index);
if(tmp !=null){
Node up = tmp.previous; //当前节点的上一个节点
Node down = tmp.next; //当前节点的下一个节点
if(up!=null){
up.next = down;
}
if(down!=null){
down.previous = up;
}
if(index == 0){
first = down;
}
if(index == size -1){
last = up;
}
}
size--;
}
public static void main(String[] args) {
LikedListTest likedListTest = new LikedListTest();
likedListTest.add("a");
likedListTest.add(123);
likedListTest.add("dfjj");
likedListTest.add("dfdg");
likedListTest.add("etr");
likedListTest.add("kjhh");
likedListTest.add("cv");
System.out.println(likedListTest.toString());
System.out.println(likedListTest.get(6));
likedListTest.remove(5);
System.out.println(likedListTest.toString());
likedListTest.remove(0);
System.out.println(likedListTest.toString());
likedListTest.remove(size - 1);
System.out.println(likedListTest.toString());
likedListTest.add(1, "kjkj");
System.out.println(likedListTest.toString());
likedListTest.add(0,"fdjkdsla");
System.out.println(likedListTest.toString());
likedListTest.add(size - 1,"gaoqi");
System.out.println(likedListTest.toString());
}
}