集合框架之collection类详解

一、集合框架的由来

Java 集合框架主要包括两种类型的容器,一种是集合(Collection),存储一个元素集合,另一种是图(Map),存储键/值对映射。Collection 接口又有 3 种子类型,List、Set和Queue,再下面是一些抽象类,最后是具体实现类,常用的有ArrayList、LinkedList、HashSet、LinkedHashSet、HashMap、LinkedHashMap 等等。

集合框架是一个用来代表和操纵集合的统一架构。所有的集合框架都包含如下内容:

  • 接口:是代表集合的抽象数据类型。例如 Collection、List、Set、Map 等。之所以定义多个接口,是为了以不同的方式操作集合对象

  • 实现(类):是集合接口的具体实现。从本质上讲,它们是可重复使用的数据结构,例如:ArrayList、LinkedList、HashSet、HashMap。

  • 算法:是实现集合接口的对象里的方法执行的一些有用的计算,例如:搜索和排序。这些算法被称为多态,那是因为相同的方法可以在相似的接口上有着不同的实现。

除了集合,该框架也定义了几个 Map 接口和类。Map 里存储的是键/值对。尽管Map不是集合,但是它们完全整合在集合中。

二、数组与集合的区别

数组的特点:

  1. 只能存储同一种数据类型的数据。
  2. 一旦初始化,长度固定。
  3. 数组中的元素与元素之间的内存地址是连续的。

注意: Object类型的数组可以存储任意类型的数据。

集合:集合是存储对象数据的集合容器。

集合比数组的优势:

  1. 集合可以存储任意类型的对象数据,数组只能存储同一种数据类型 的数据。
  2. 集合的长度是会发生变化的,数组的长度是固定的

三、collection之继承体系

Collection<E>接口是所有单列集合的共同父接口,下面列出了常用的Collection子类集合及其继承关系。

集合框架概述

Collection   
    |-----List有序(存储顺序和取出顺序一致),可重复
    |----ArrayList,线程不安全,底层使用数组实现,查询快,增删慢。效率高。
            每次容量不足时,自增长度的一半,如下源码可知
                  int newCapacity = oldCapacity + (oldCapacity >> 1);
    |----LinkedList , 线程不安全,底层使用链表实现,查询慢,增删快。效率高
 
    |----Vector , 线程安全,底层使用数组实现,查询快,增删慢。效率低         每次容量不足时,默认自增长度的一倍(如果不指定增量的话),如下源码可知
                   int newCapacity = oldCapacity + ((capacityIncrement > 0) ?
                                     capacityIncrement : oldCapacity);
    |-----Set   元素唯一一个不包含重复元素的 collection。更确切地讲,set 不包含满足 e1.equals(e2) 的元素对 e1 和 e2,并且最多包含一个 null 元素。
 
    |--HashSet 底层是由HashMap实现的,通过对象的hashCode方法与equals方法来保证插入元素的唯一性,无序(存储顺序和取出顺序不一致)。
 
    |--LinkedHashSet 底层数据结构由哈希表和链表组成。哈希表保证元素的唯一性,链表保证元素有序。(存储和取出是一致)
 
    |--TreeSet 基于 TreeMap 的 NavigableSet 实现。使用元素的自然顺序对元素进行排序,或者根据创建 set 时提供的 Comparator 进行排序,具体取决于使用的构造方法。 元素唯一。

四、Collection泛型接口

boolean add(E e) 
             确保此 collection 包含指定的元素(可选操作)。    
    boolean addAll(Collection<? extends E> c) 
   将指定collection中的所有元素都添加到此collection 中(可选操作)。    
    void clear() 
             移除此 collection 中的所有元素(可选操作)。 
    boolean contains(Object o) 
             如果此 collection 包含指定的元素,则返回 true。 
    boolean containsAll(Collection<?> c) 
             如果此 collection 包含指定 collection 中的所有元素,则返回 true。 
    boolean equals(Object o) 
             比较此 collection 与指定对象是否相等。 
    int hashCode() 
             返回此 collection 的哈希码值。 
    boolean isEmpty() 
             如果此 collection 不包含元素,则返回 true。 
    Iterator<E> iterator() 
             返回在此 collection 的元素上进行迭代的迭代器。 
    boolean remove(Object o) 
             从此 collection 中移除指定元素的单个实例,如果存在的话(可选操作)。 
    boolean removeAll(Collection<?> c) 
             移除此 collection 中那些也包含在指定 collection 中的所有元素(可选操作)。 
    boolean retainAll(Collection<?> c) 
             仅保留此 collection 中那些也包含在指定 collection 的元素(可选操作)。 
    int size() 
             返回此 collection 中的元素数。 
    Object[] toArray() 
             返回包含此 collection 中所有元素的数组。 
   <T> T[] 
    toArray(T[] a) 

collection方法简单示例:

    //集合转数组遍历
	public static void demo1() {
	Collection coll = new ArrayList();
			coll.add(new Student("张三",23));		//Object obj = new Student("张三",23);
			coll.add(new Student("李四",24));
			coll.add(new Student("王五",25));
			coll.add(new Student("赵六",26));
			
			Object[] arr = coll.toArray();				//将集合转换成数组
			for (int i = 0; i < arr.length; i++) {
				Student s = (Student)arr[i];			//强转成Student
				System.out.println(s.getName() + "," + s.getAge());
			}
	} 
	
	//集合的遍历之迭代器遍历
	public static void demo2() {
	Collection c = new ArrayList();
			c.add("a");
			c.add("b");
			c.add("c");
			c.add("d");
			
			Iterator it = c.iterator();						//获取迭代器的引用
			while(it.hasNext()) {							//集合中的迭代方法(遍历)
				System.out.println(it.next());
			}
	}		

五、List泛型接口

public interface List<E>extends Collection<E>  //超级接口

方法概述:

 boolean add(E o) 
          向列表的尾部追加指定的元素(可选操作)。 
 void add(int index, E element) 
          在列表的指定位置插入指定元素(可选操作)。 
 boolean addAll(Collection<? extends E> c) 
          追加指定 collection 中的所有元素到此列表的结尾,顺序是指定 collection 的迭代器返回这些元素的顺序(可选操作)。 
 boolean addAll(int index, Collection<? extends E> c) 
          将指定 collection 中的所有元素都插入到列表中的指定位置(可选操作)。 
 void clear() 
          从列表中移除所有元素(可选操作)。 
 boolean contains(Object o) 
          如果列表包含指定的元素,则返回 true。 
 boolean containsAll(Collection<?> c) 
          如果列表包含指定 collection 的所有元素,则返回 true。 
 boolean equals(Object o) 
          比较指定的对象与列表是否相等。 
 E get(int index) 
          返回列表中指定位置的元素。 
 int hashCode() 
          返回列表的哈希码值。 
 int indexOf(Object o) 
          返回列表中首次出现指定元素的索引,如果列表不包含此元素,则返回 -1。 
 boolean isEmpty() 
          如果列表不包含元素,则返回 true。 
 Iterator<E> iterator() 
          返回以正确顺序在列表的元素上进行迭代的迭代器。 
 int lastIndexOf(Object o) 
          返回列表中最后出现指定元素的索引,如果列表不包含此元素,则返回 -1。 
 ListIterator<E> listIterator() 
          返回列表中元素的列表迭代器(以正确的顺序)。 
 ListIterator<E> listIterator(int index) 
          返回列表中元素的列表迭代器(以正确的顺序),从列表的指定位置开始。 
 E remove(int index) 
          移除列表中指定位置的元素(可选操作)。 
 boolean remove(Object o) 
          移除列表中出现的首个指定元素(可选操作)。 
 boolean removeAll(Collection<?> c) 
          从列表中移除指定 collection 中包含的所有元素(可选操作)。 
 boolean retainAll(Collection<?> c) 
          仅在列表中保留指定 collection 中所包含的元素(可选操作)。 
 E set(int index, E element) 
          用指定元素替换列表中指定位置的元素(可选操作)。 
 int size() 
          返回列表中的元素数。 
 List<E> subList(int fromIndex, int toIndex) 
          返回列表中指定的 fromIndex(包括 )和 toIndex(不包括)之间的部分视图。 
 Object[] toArray() 
          返回以正确顺序包含列表中的所有元素的数组。 
<T> T[] 
 toArray(T[] a) 
          返回以正确顺序包含列表中所有元素的数组;返回数组的运行时类型是指定数组的运行时类型。

list方法简单示例:

	public static void demo2() {
		List list = new ArrayList();
		list.add(new Student("张三",23));
		list.add(new Student("李四",24));
		list.add(new Student("王五",25));
		list.add(new Student("赵六",26));
		
		Iterator iterator = list.iterator();
		while (iterator.hasNext()) {
			Student s = (Student) iterator.next(); //向下转型
			System.out.println(s);
		}
	}
	
	public static void demo() {
		List list = new ArrayList();
		list.add("a");
		list.add("b");
		list.add("c");
		list.add("d");
		
		Iterator iterator  = list.iterator();
		while (iterator.hasNext()) {
			System.out.println(iterator.next());
		}
	}
}

并发修改异常产生的原因及解决方案

假设有一个集合,请问,我想判断里面有没有"world"这个元素,如果有,我就添加一个"java"元素,具体代码如下:

public static void demo3() {
		List list = new ArrayList();
		list.add("a");
		list.add("b");
		list.add("world");
		list.add("d");
		list.add("e");
		
		Iterator it = list.iterator();
		while(it.hasNext()) {
			String str = (String)it.next();
			if(str.equals("world")) {
				list.add("javaee");			//这里会抛出ConcurrentModificationException并发修改异常
			}
		}
	}

运行上面代码发生ConcurrentModificationException并发修改异常,查看迭代器源代码如下。
产生原因:迭代器是依赖于集合而存在的,在判断成功后,集合的中新添加了元素,而迭代器却不知道,迭代器的内容不发生改变。所以就报错了,这个错叫并发修改异常。

      final void checkForComodification() {
            if (modCount != expectedModCount)
                throw new ConcurrentModificationException();
        }
    }

解决办法及代码如下:
迭代器迭代元素,迭代器修改元素(ListIterator的特有功能add)
集合遍历元素,集合修改元素

    public static void demo() {
		ListIterator lit = list.listIterator();		//如果想在遍历的过程中添加元素,可以用ListIterator中的add方法
			while(lit.hasNext()) {
				String str = (String)lit.next();
				if(str.equals("world")) {
					lit.add("javaee");	
					//list.add("javaee");
				}
            }	
		}

了解:(ListIterator)

  1. boolean hasNext()是否有下一个
  2. boolean hasPrevious()是否有前一个
  3. Object next()返回下一个元素
  4. Object previous();返回上一个元素

六、ArrayList类

方法摘要:

public class ArrayList<E>extends AbstractList<E>implements List<E>, RandomAccess, Cloneable, Serializable

构造方法摘要

ArrayList() 
          构造一个初始容量为 10 的空列表。 
ArrayList(Collection<? extends E> c) 
          构造一个包含指定 collection 的元素的列表,这些元素是按照该 collection 的迭代器返回它们的顺序排列的。 
ArrayList(int initialCapacity) 
          构造一个具有指定初始容量的空列表。 
 

 boolean add(E o) 
          将指定的元素追加到此列表的尾部。 
 void add(int index, E element) 
          将指定的元素插入此列表中的指定位置。 
 boolean addAll(Collection<? extends E> c) 
          按照指定 Collection 的迭代器所返回的元素顺序,将该 Collection 中的所有元素追加到此列表的尾部。 
 boolean addAll(int index, Collection<? extends E> c) 
          从指定的位置开始,将指定 Collection 中的所有元素插入到此列表中。 
 void clear() 
          移除此列表中的所有元素。 
 Object clone() 
          返回此 ArrayList 实例的浅表复制。 
 boolean contains(Object elem) 
          如果此列表中包含指定的元素,则返回 true。 
 void ensureCapacity(int minCapacity) 
          如有必要,增加此 ArrayList 实例的容量,以确保它至少能够容纳最小容量参数所指定的元素数。 
 E get(int index) 
          返回此列表中指定位置上的元素。 
 int indexOf(Object elem) 
          搜索给定参数第一次出现的位置,使用 equals 方法进行相等性测试。 
 boolean isEmpty() 
          测试此列表中是否没有元素。 
 int lastIndexOf(Object elem) 
          返回指定的对象在列表中最后一次出现的位置索引。 
 E remove(int index) 
          移除此列表中指定位置上的元素。 
 boolean remove(Object o) 
          从此列表中移除指定元素的单个实例(如果存在),此操作是可选的。 
protected  void removeRange(int fromIndex, int toIndex) 
          移除列表中索引在 fromIndex(包括)和 toIndex(不包括)之间的所有元素。 
 E set(int index, E element) 
          用指定的元素替代此列表中指定位置上的元素。 
 int size() 
          返回此列表中的元素数。 
 Object[] toArray() 
          返回一个按照正确的顺序包含此列表中所有元素的数组。 
<T> T[] 
 toArray(T[] a) 
          返回一个按照正确的顺序包含此列表中所有元素的数组;返回数组的运行时类型就是指定数组的运行时类型。 
 void trimToSize() 
          将此 ArrayList 实例的容量调整为列表的当前大小。 
从类 java.util.AbstractList 继承的方法 
equals, hashCode, iterator, listIterator, listIterator, subList 
  从类 java.util.AbstractCollection 继承的方法 
containsAll, removeAll, retainAll, toString 
  从类 java.lang.Object 继承的方法 
finalize, getClass, notify, notifyAll, wait, wait, wait 
  从接口 java.util.List 继承的方法 
containsAll, equals, hashCode, iterator, listIterator, listIterator, removeAll, retainAll, subList  

ArrayList示例:

	public static void demo1() {
		ArrayList arr = new ArrayList();
		arr.add(new Student("张三", 23));
		arr.add(new Student("李四",24));
		
		System.out.println(arr);
		
		Iterator it = arr.iterator();
		while (it.hasNext()) {
			Student student = (Student) it.next();
			System.out.println(student.getName()+"..."+student.getAge());
		}
	}
 
	public static void demo() {
		ArrayList arr = new ArrayList();
		arr.add("a");
		arr.add("b");
		arr.add("c");
		arr.add("d");
		
		System.out.println(arr);
	}
 
}

七、LinkedList类

public class LinkedList<E>extends AbstractSequentialList<E>implements List<E>, Queue<E>, Cloneable, Serializable

构造方法摘要

LinkedList() 
          构造一个空列表。 
LinkedList(Collection<? extends E> c) 
          构造一个包含指定集合中的元素的列表,这些元素按其集合的迭代器返回的顺序排列。 

方法摘要

 boolean add(E o) 
          将指定元素追加到此列表的结尾。 
 void add(int index, E element) 
          在此列表中指定的位置插入指定的元素。 
 boolean addAll(Collection<? extends E> c) 
          追加指定 collection 中的所有元素到此列表的结尾,顺序是指定 collection 的迭代器返回这些元素的顺序。 
 boolean addAll(int index, Collection<? extends E> c) 
          将指定集合中的所有元素从指定位置开始插入此列表。 
 void addFirst(E o) 
          将给定元素插入此列表的开头。 
 void addLast(E o) 
          将给定元素追加到此列表的结尾。 
 void clear() 
          从此列表中移除所有元素。 
 Object clone() 
          返回此 LinkedList 的浅表复制。 
 boolean contains(Object o) 
          如果此列表包含指定元素,则返回 true。 
 E element() 
          找到但不移除此列表的头(第一个元素)。 
 E get(int index) 
          返回此列表中指定位置处的元素。 
 E getFirst() 
          返回此列表的第一个元素。 
 E getLast() 
          返回此列表的最后一个元素。 
 int indexOf(Object o) 
          返回此列表中首次出现的指定元素的索引,如果列表中不包含此元素,则返回 -1。 
 int lastIndexOf(Object o) 
          返回此列表中最后出现的指定元素的索引,如果列表中不包含此元素,则返回 -1。 
 ListIterator<E> listIterator(int index) 
          返回此列表中的元素的列表迭代器(按适当顺序),从列表中指定位置开始。 
 boolean offer(E o) 
          将指定元素添加到此列表的末尾(最后一个元素)。 
 E peek() 
          找到但不移除此列表的头(第一个元素)。 
 E poll() 
          找到并移除此列表的头(第一个元素)。 
 E remove() 
          找到并移除此列表的头(第一个元素)。 
 E remove(int index) 
          移除此列表中指定位置处的元素。 
 boolean remove(Object o) 
          移除此列表中首次出现的指定元素。 
 E removeFirst() 
          移除并返回此列表的第一个元素。 
 E removeLast() 
          移除并返回此列表的最后一个元素。 
 E set(int index, E element) 
          将此列表中指定位置的元素替换为指定的元素。 
 int size() 
          返回此列表的元素数。 
 Object[] toArray() 
          以正确顺序返回包含此列表中所有元素的数组。 
<T> T[] 
 toArray(T[] a) 
          以正确顺序返回包含此列表中所有元素的数组;返回数组的运行时类型即为指定数组的类。

八、vector

public class Vector<E>extends AbstractList<E>implements List<E>, RandomAccess, Cloneable, Serializable

构造方法摘要

Vector() 
          构造一个空向量,使其内部数据数组的大小为 10,其标准容量增量为零。 
Vector(Collection<? extends E> c) 
          构造一个包含指定集合中的元素的向量,这些元素按其集合的迭代器返回元素的顺序排列。 
Vector(int initialCapacity) 
          使用指定的初始容量和等于零的容量增量构造一个空向量。 
Vector(int initialCapacity, int capacityIncrement) 
          使用指定的初始容量和容量增量构造一个空的向量 

特有方法摘要

 boolean add(E o) 
          将指定元素追加到此向量的末尾。 
 void add(int index, E element) 
          在此向量的指定位置插入指定的元素。 
 boolean addAll(Collection<? extends E> c) 
          将指定 Collection 中的所有元素追加到此向量的末尾,按照指定集合的迭代器所返回的顺序追加这些元素。 
 boolean addAll(int index, Collection<? extends E> c) 
          在指定位置将指定 Collection 中的所有元素插入到此向量中。 
 void addElement(E obj) 
          将指定的组件添加到此向量的末尾,将其大小增加 1。 
 int capacity() 
          返回此向量的当前容量。 
 void clear() 
          从此向量中移除所有元素。 
 Object clone() 
          返回向量的一个副本。 
 boolean contains(Object elem) 
          测试指定的对象是否为此向量中的组件。 
 boolean containsAll(Collection<?> c) 
          如果此向量包含指定 Collection 中的所有元素,则返回 true。 
 void copyInto(Object[] anArray) 
          将此向量的组件复制到指定的数组中。 
 E elementAt(int index) 
          返回指定索引处的组件。 
 Enumeration<E> elements() 
          返回此向量的组件的枚举。 
 void ensureCapacity(int minCapacity) 
          增加此向量的容量(如有必要),以确保其至少能够保存最小容量参数指定的组件数。 
 boolean equals(Object o) 
          比较指定对象与此向量的相等性。 
 E firstElement() 
          返回此向量的第一个组件(位于索引 0 处的项)。 
 E get(int index) 
          返回向量中指定位置的元素。 
 int hashCode() 
          返回此向量的哈希码值。 
 int indexOf(Object elem) 
          搜索给定参数的第一个匹配项,使用 equals 方法测试相等性。 
 int indexOf(Object elem, int index) 
          搜索给定参数的第一个匹配项,从 index 处开始搜索,并使用 equals 方法测试其相等性。 
 void insertElementAt(E obj, int index) 
          将指定对象作为此向量中的组件插入到指定的 index 处。 
 boolean isEmpty() 
          测试此向量是否不包含组件。 
 E lastElement() 
          返回此向量的最后一个组件。 
 int lastIndexOf(Object elem) 
          返回指定的对象在此向量中最后一个匹配项的索引。 
 int lastIndexOf(Object elem, int index) 
          向后搜索指定的对象,从指定的索引处开始搜索,并返回一个索引。 
 E remove(int index) 
          移除此向量中指定位置的元素。 
 boolean remove(Object o) 
          移除此向量中指定元素的第一个匹配项,如果向量不包含该元素,则元素保持不变。 
 boolean removeAll(Collection<?> c) 
          从此向量中移除包含在指定 Collection 中的所有元素。 
 void removeAllElements() 
          从此向量中移除全部组件,并将其大小设置为零。 
 boolean removeElement(Object obj) 
          从此向量中移除变量的第一个(索引最小的)匹配项。 
 void removeElementAt(int index) 
          删除指定索引处的组件。 
protected  void removeRange(int fromIndex, int toIndex) 
          从此 List 中移除其索引位于 fromIndex(包括)与 toIndex(不包括)之间的所有元素。 
 boolean retainAll(Collection<?> c) 
          在此向量中仅保留包含在指定 Collection 中的元素。 
 E set(int index, E element) 
          用指定的元素替换此向量中指定位置处的元素。 
 void setElementAt(E obj, int index) 
          将此向量指定 index 处的组件设置为指定的对象。 
 void setSize(int newSize) 
          设置此向量的大小。 
 int size() 
          返回此向量中的组件数。 
 List<E> subList(int fromIndex, int toIndex) 
          返回此 List 的部分视图,元素范围为从 fromIndex(包括)到 toIndex(不包括)。 
 Object[] toArray() 
          返回一个数组,包含此向量中以正确顺序存放的所有元素。 
<T> T[] 
 toArray(T[] a) 
          返回一个数组,包含此向量中以正确顺序存放的所有元素;返回数组的运行时类型为指定数组的类型。 
 String toString() 
          返回此向量的字符串表示形式,其中包含每个元素的 String 表示形式。 
 void trimToSize() 
          对此向量的容量进行微调,使其等于向量的当前大小。

vector 使用示例:

	public static void demo1() {
		Vector v = new Vector();
		v.add(new Student("张三", 23));
		v.add(new Student("李四", 24));
		v.add(new Student("王五", 25));
		
		Iterator it = v.iterator();
		while (it.hasNext()) {
			Object s = (Student) it.next();
			System.out.println(s);
		}
	}
	
	public static void demo() {
		Vector v = new Vector();
		v.add("a");
		v.add("b");
		v.add("c");
		v.add("d");
		
		System.out.println(v);
		System.out.println(v.capacity());
		System.out.println(v.size());
		System.out.println(v.contains("a"));
	}

猜你喜欢

转载自blog.csdn.net/qq_39478237/article/details/81530522