1.集合类和容器类的继承关系图:
说明:上图来自互联网,如有侵权,请告之,我将注明原始作者或删除该图。
上图只列出了图中类的一些主要继承和实现关系,并不精确,只表示了大概的关系,有些父接口并没有在图中画出,以及有写继承关系跨过了中间的某些类,图中让它直接继承了间接父类。
2.对各个集合类的一些说明:
1.Collection是集合的父类,但是JDK不提供直接继承自Collection的集合类让用户使用,而是提供继承自Collection子接口List和Set的集合类让用户使用。
2.List和Set的区别,List提供了随机访问的方法,内部元素是有序的,并且允许为空;而实现Set接口的类,内部元素是无序的,并且最多只能有一个null元素,并且放入Set中的元素必须不相等,就是要满足e1.equals(e2)==false,另外必须小心操作可变对象,当Set中的可变对象被操作后使得Set中有两个元素满足了e1.equals(e2)==true时就会发生一些问题。
3.ArrayList类。ArrayList实现了可变大小的数组。它允许所有元素,包括null。ArrayList没有同步。每个ArrayList实例都有一个容量(Capacity),即用于存储元素的数组的大小。这个容量可随着不断添加新元素而自动增加,但是增长算法并没有定义。当需要插入大量元素时,在插入前可以调用ensureCapacity方法来增加ArrayList的容量以提高插入效率。
4.LikedList。它内部的结构是基于链表的。LinkedList实现了List接口,允许null元素。此外LinkedList实现了Deque<E>, Queue<E>接口,提供额外的get,remove,insert方法在LinkedList的首部或尾部。所以LinkedList可以用来实现队列操作。它也是非同步的。
5.Vector。它与ArrayList非常相似,但是Vector是同步的。
6.HashSet。它内部是使用Hash表来存放元素的,通过HashMap来实现的。元素是无序的。
7.TreeSet。它内部结构是基于红黑树的,内部元素是有序的。插入、删除等操作是
3.对各个容器类的一些说明:
1.容器的父接口是Map,它提供了键值对的数据结构。
2.HashMap。跟HashSet相似,它也是基于Hash函数的,所以作为HashMap的键值的类,必须重写hash和equals方法。它是非同步的,允许null的key和null的value。
3.Hashtable。它也是实现Map的一个子类,它跟HashMap非常相似,但是Hashtable是同步的,并且不允许有null的key和null的value。
4.TreeMap。内部结构是基于红黑树的,内部的键值集合是有序的,可以进行基于有序的相关操作,其他操作跟HashMap相似。
5.WeakHashMap。该类与HashMap相似,只是它对key实行“弱引用”,如果一个key不再被外部所引用,那么该key可以被GC回收。
4.Collections类:
1.这是一个工具类,它的静态方法一般用来处理集合容器类,或者用来生产集合容器类。Collections.synchronizedXXX()方法可以从非同步的集合容器类获得同步的集合容器类。
5.Arrays类:
1.Arrays类提供了很多处理数组相关的静态方法,如数组的查找、比较、排序等操作。另外该类还提供了一个静态方法,将数组转换成List,该方法就是
Arrays.asList(T ... array);
6.同步的集合类以及容器类(Synchronized):
1.一般的集合类和容器类都是非同步的(除了Vector和Hashtable以及它们的子类),如果用在多线程环境下必须自己写有关同步的代码。JDK中为我们提供了与一般集合容器类相应的同步类,SynchronizedCollection<E>、SynchronizedList<E>、SynchronizedMap<E>、SynchronizedSet<E>、SynchronizedSortedSet<E>、SynchronizedMap<E>,这些类都是Collections类中的静态内部类,通过Collections.synchronizedXXX()方法就可以获得相关的同步集合容器类,并且得到的同步类与作为参数的非同步类共享数据空间,当在同步类中对集合或者容器做出修改,在非同步的类中能同步感受到。例如:
List< String> list = new LinkedList<>();
list.add("one");
List<String> list1 = Collections.synchronizedList(list);
list1.remove(0);
System.out.println(list.size());
上述代码输出结果为0.
7.并发的集合类以及容器类:
1.同步集合或容器中,基本上在内部是使用synchronized来实现的,而且一个类中所有的方法使用的是同一个锁对象,在很多这会造成性能上的问题。另外,有一些复合操作,需要保持原子性,如获取最后一个元素(代码见下面),而同步类这时候就做不到了,所以这时候要考虑使用并发类了,并发类位于java.util.concurrent中。
/**
*获取最后一个元素
*/
public static Object getLast(Vector list) {
int lastIndex = list.size() - 1;
return list.get(lastIndex);
}
2.并发容器有ConcurrentHashMap,它采用更细粒度的锁,被称为分段锁,允许一定数量的线程并发的修改它,能够提供高并发的性能。
3.还有一些有用的适用于某些并发场合的集合类,CopyOnWriteArrayList等。
4.在这里只要Java中存在同步集合容器和并发集合容器类就可以了,当遇到多线程的情况或者要求并发的情况下,再去找相关的合适的同步或并发的集合容器类。