Java总结_百宝袋集合类(2)List


在这里插入图片描述

1、List接口

  List是有序可重复的集合(也称为列表)。它在Collection接口的基础上新增了一些与索引相关的方法,其中包括:

  1. add(int index, E element):在索引处添加元素;
  2. addAll(int index, Collection<? extends E> c):在索引处添加集合;
  3. get(int index):获取索引处的元素;
  4. indexOf(Object o):返回元素第一次出现在列表中的索引位置;
  5. lastIndexOf(Object o):返回最后一次出现在列表中的索引位置;
  6. remove(int index):删除指定索引中的元素;
  7. set(int index, E element):用新元素代替指定索引处的元素;
  8. subList(int fromIndex, int toIndex)返回指定索引范围中的元素形成新的列表;
  9. listIterator(int index)或listIterator():返回列表迭代器;

  List接口的实现类有ArrayListLinkedList;在JDK8中,ArrayList除了实现List接口外,还实现了RandomAccess、Cloneable、Serializable,以及继承AbstractList抽象类;
而LinkedList实现了Deque, Cloneable, Serializable,以及继承AbstractSequentialList;

2、ArrayList
2.1、ArrayList特征

(1) 有序集合(输出顺序==输入顺序),因为底层是通过数组来存储元素;

/*
采用transient修饰成员变量,使得默认对象序列化时对elementData存储失效,之所以如此定义,
是因为elementData数组并不是装满了元素,真正有元素的大小为size,
所以可通过覆盖readObject和writeObject方法自定义对elementData的序列化
*/
transient Object[] elementData;
 

在这里插入图片描述
(2) 动态扩容,最大可容Integer.MAX_VALUE个元素,在通过new ArrayList()创建列表时,默认初始容量大小为DEFAULT_CAPACITY=10;

private void ensureExplicitCapacity(int minCapacity) {
		//修改次数加1
        modCount++;
      	//elemntData数组长度小于minCapacity时发生扩容
        if (minCapacity - elementData.length > 0)
            grow(minCapacity);//核心动态扩容机制
 }
    
private void grow(int minCapacity) {
        // overflow-conscious code
        int oldCapacity = elementData.length;
        //newCapacity为1.5倍的oldCapacity
        int newCapacity = oldCapacity + (oldCapacity >> 1);
        //与最小容量值minCapacity比较
        if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;
        if (newCapacity - MAX_ARRAY_SIZE > 0)
        	//限制最大可容元素大小为Integer.MAX_VALUE
            newCapacity = hugeCapacity(minCapacity);      
        //动态扩容
        elementData = Arrays.copyOf(elementData, newCapacity);
        
}

(3) 线程不安全,因为在实现和继承的方法中不包含lock和synchronized字眼;
(4) 增删改查速度快
  前面已经说明ArrayList底层采用数组来存储数据,那么我们自认为增删数据速度应该比LinkedList慢很多,但是从源码中可以看到增删方法采用JVM固有的System. arrayCopy()方法进行了效率优化,所以当元素量大的时候,其速度会比用For循环快些;

2.2ArrayList简单用法

LinkedList一样可以用

package xw.zx.collection;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;

public class ListDemo {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		List<String> l=new ArrayList<String>();
		//添加元素
		l.add("1");//索引从0开始
		l.add(1,"2");//在索引1处添加字符串2		
		l.addAll(Arrays.asList("3","4","5"));//在size后添加集合内的元素
		/**
		 * 在索引处添加集合中的元素,当index<size的时候,[index,size]范围内的数据将被移到最后面
		 * 本例中元素5被移到了列表的末尾;
		 */		
		l.addAll(4,Arrays.asList("6","7","8"));
		System.out.println(l);//[1, 2, 3, 4, 6, 7, 8, 5]
		//删除元素
		l.remove(2);//删除索引处的元素
		l.remove("5");//删除元素"5";
		/**
		 * 删除参数集合中包含的元素
		 * 参数集合中可包含l列表中未存在的元素,比如“9”
		 */
		l.removeAll(Arrays.asList("4","7","9"));
		System.out.println(l);//[1, 2, 6, 8]
		
		//修改元素
		l.set(1,"6");//将索引1中的元素替换成元素“6”,可见列表元素可重复
		System.out.println(l);//[1, 6, 6, 8]		
		
		//返回子列表,包括fromIndex,不包括toIndex
		List<String> sub=l.subList(1, 3);
		System.out.println(sub);//[6,6]
		
		//将列表转化为数组
		String[] arr=l.toArray(new String[2] );
		System.out.println(Arrays.deepToString(arr));//[1,6,6,8]
		
		//支持双向遍历
		ListIterator<String> listIterator=l.listIterator(l.size());
		while(listIterator.hasPrevious()) {
			//向后遍历
			System.out.print(listIterator.previous()+" ");
		}//8 6 6 1
		System.out.println();
	    while(listIterator.hasNext()) { 
	    	//向前遍历
	    	System.out.print(listIterator.next()+" ");
	    }//1 6 6 8
		 
		
				
	}

}
3、LinkedList
3.1LinkedList特征

(1) 采用双向链式结构存储数据,使得元素的增、删速度快;

   //链首节点
    transient Node<E> first;

  //链尾节点
    transient Node<E> last;

在这里插入图片描述
(2) 实现了Deque接口方法,除了List接口方法可使用外,还可用于实现队列Queue(FIFO)、栈Stack(LIFO)结构特征;下面以实现队列为例

package xw.zx.collection;

import java.util.LinkedList;

public class TestQueue<E> {
	 private LinkedList<E> list = new LinkedList<E>();
	 /**
	  * 清空队列
	  */
	  public void clear()
	  {
		  list.clear();
	  }
	  /**
	   * 判断队列是否为空
	   * @return
	   */
	  public boolean isEmpty()
	  {
		  return list.isEmpty();
	  }
	  /**
	   * 在队尾中插入元素
	   * @param e
	   */
	  public void push(E  e)
	  {
		  list.addLast(e);
	  }
	  /**
	   * 从队首中弹出元素
	   * @return
	   */
	  public E poll()
	  {
		  if(!list.isEmpty())
		  {
			  return list.removeFirst();
		  }
		  return null;
	  }	
	  /**
	   * 队列元素的大小
	   * @return
	   */
	  public int size()
	  {
		  return list.size();
	  }
	  /**
	   * 返回队首的元素
	   * @return
	   */
	  public E peek()
	  {
		  return list.getFirst();
	  }
	  /**
	   * 测试
	   * @param args
	   */
	  public static void main(String[] args)
	  {
		  TestQueue<String> queue = new TestQueue<String>();		  
		  queue.push("1");//推进元素
		  queue.push("2");
		  queue.push("3");	
		  System.out.println("判断是否队列是否为空:"+queue.isEmpty());
		  System.out.println("返回队列大小:"+queue.size());
		  System.out.println("弹出队首元素,并删除队首元素:"+queue.poll());		 
		  System.out.println("获取队首元素:"+queue.peek());		
		  queue.clear();
		  System.out.println("判断是否队列是否为空:"+queue.isEmpty());
	  }

	
}

(3) 查寻速度慢,由于采用双向链式表存储数据,所以每次查寻元素都需要从链头或链尾挨个节点遍历查找;

//JDK8源码LinkedList中的get方法
public E get(int index) {
		//检查index有没有超出size大小
        checkElementIndex(index);
        //调用node方法返回元素值
        return node(index).item;
}
//JDK8源码LinkedList中的node方法
Node<E> node(int index) {  
		//判断index是靠近链前还是链后,然后在决定遍历方式  
        if (index < (size >> 1)) {
            Node<E> x = first;
            for (int i = 0; i < index; i++)
                x = x.next;
            return x;
        } else {
            Node<E> x = last;
            for (int i = size - 1; i > index; i--)
                x = x.prev;
            return x;
       }
  }

4、总结

(1)List的所有实现类都是有序可重复的,ArrayList底层是使用数组存储,LinkedList采用双向链表;
(2)ArrayList比LinkedList更常用一些,因为它的增删改查速度都快(增删采用System.arrayCopy()优化),而LinkedList的查寻速度比较慢,需要从链头或链尾挨个遍历查寻;
(3)LinkedList适用于构造队列Queue、栈Stack数据结构;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值