目录
一、概述
java中定义了很多接口,表示不同的数据结构,也提供了不同的接口实现。接口分为两类:collection和map。很多接口都有不同的实现,不同实现的差异在于内部数据存储结构不同,导致存取效率不一致,内部数据是否有序。
数据结构有数组、链表、队列、双端队列、集合、栈、映射,而java集合包都有对应的实现,栈没有对应接口。
下面给出接口的层次结构:
- java.lang.Iterable<T>
- java.util.Collection<E>
- java.util.Map<K,V>
- java.util.SortedMap<K,V>
- java.util.NavigableMap<K,V>
- java.util.SortedMap<K,V>
下面给出接口实现类的层次结构:
- java.util.AbstractCollection<E> (implements java.util.Collection<E>)
- java.util.AbstractList<E> (implements java.util.List<E>)
- java.util.AbstractSequentialList<E>
- java.util.LinkedList<E> (implements java.lang.Cloneable, java.util.Deque<E>, java.util.List<E>, java.io.Serializable)
- java.util.ArrayList<E> (implements java.lang.Cloneable, java.util.List<E>, java.util.RandomAccess, java.io.Serializable)
- java.util.Vector<E> (implements java.lang.Cloneable, java.util.List<E>, java.util.RandomAccess, java.io.Serializable)
- java.util.Stack<E>
- java.util.AbstractSequentialList<E>
- java.util.AbstractQueue<E> (implements java.util.Queue<E>)
- java.util.PriorityQueue<E> (implements java.io.Serializable)
- java.util.AbstractSet<E> (implements java.util.Set<E>)
- java.util.EnumSet<E> (implements java.lang.Cloneable, java.io.Serializable)
- java.util.HashSet<E> (implements java.lang.Cloneable, java.io.Serializable, java.util.Set<E>)
- java.util.LinkedHashSet<E> (implements java.lang.Cloneable, java.io.Serializable, java.util.Set<E>)
- java.util.TreeSet<E> (implements java.lang.Cloneable, java.util.NavigableSet<E>, java.io.Serializable)
- java.util.ArrayDeque<E> (implements java.lang.Cloneable, java.util.Deque<E>, java.io.Serializable)
- java.util.AbstractList<E> (implements java.util.List<E>)
- java.util.AbstractMap<K,V> (implements java.util.Map<K,V>)
- java.util.EnumMap<K,V> (implements java.lang.Cloneable, java.io.Serializable)
- java.util.HashMap<K,V> (implements java.lang.Cloneable, java.util.Map<K,V>, java.io.Serializable)
- java.util.LinkedHashMap<K,V> (implements java.util.Map<K,V>)
- java.util.IdentityHashMap<K,V> (implements java.lang.Cloneable, java.util.Map<K,V>, java.io.Serializable)
- java.util.TreeMap<K,V> (implements java.lang.Cloneable, java.util.NavigableMap<K,V>, java.io.Serializable)
- java.util.WeakHashMap<K,V> (implements java.util.Map<K,V>)
- java.util.Dictionary<K,V>
- java.util.Hashtable<K,V> (implements java.lang.Cloneable, java.util.Map<K,V>, java.io.Serializable)
- java.util.Properties
- java.util.Hashtable<K,V> (implements java.lang.Cloneable, java.util.Map<K,V>, java.io.Serializable)
二、接口及实现类
2.1、List
List接口代表列表,元素可重复。实现类有LinkedList、ArrayList、Vector、Stack。LinkedList内部实现为链表。ArrayList由数组实现,可自动扩容,线程不安全。Vector和ArrayList类似,线程安全。Stack被实现为栈,后进先出。
2.2、Set
set接口代表集合,元素不能重复。实现类如上层次结构所示,但重要的有HashSet、TreeSet和LinkedHashSet。查看它的源码可知,这三个类都由对应的Map实现(HashMap、TreeMap和LinkedHashMap)。遍历Set时,HashSet和LinkedHashSet的元素顺序不确定,而TreeMap可以确定的,为排好序的顺序,也可以传入Comparator自定义顺序(因为实现了NavigableSet)。
2.3、Map
Map代表key到value的映射。其中HashMap的key和value都可以为null,线程不安全的,而HashTable的key和value都不能为null,线程安全的。TreeMap内部元素的顺序是确定的,因此遍历时可以得到排序后的元素,也可以传入Comparator自定义顺序(因为实现了NavigableMap)。
2.4、Queue
Queue接口代表队列,先进先出,也就是队列末尾插入,队列头删除。实现类有LinkedList和PriorityQueue。
2.5、Deque
Deque接口代表双端队列,可以在队列两端进行插入删除。实现类有LinkedList和ArrayDeque。
2.6、栈
先进后出,没有对应接口,但是可由LinkedList和Stack代替。
三、其他
3.1、hashCode()和equals()
在hash表中,如HashTable、HashMap或HashSet中插入一元素时,先利用hashCode()方法得到hash值,该值指定了元素在hash表内部的存放位置,不同元素可能会对应相同hash值,因此可能产生冲突,利用equals判断相同位置的元素是否为同一元素,然后放入不同位置。因此当访问相同hash值的不同元素时还需要equals函数判断元素是否为所找元素。
因此如果利用hash表作为复杂对象的容器,最好实现他的hashCode和equals函数。
3.2、排序
使用java.util.Collections.sort()方法可以实现排序。排序有两种方法,一是使用排序对象的自然顺序,该对象必须实现Comparable接口。
List list = new ArrayList();
//add elements to the list
Collections.sort(list);
二是定义一个Comparator来排序list:
List list = new ArrayList();
//add elements to the list
Comparator comparator = new SomeComparator();
Collections.sort(list, comparator);
3.3、Collections和Arrays
Collections是对集合操作的工具类,而Arrays是数组的工具类。
四、流
集合的流不同于io的流,集合的流是集合中元素组成的流,而io流是字节流或字符流。通过流和lambda表达式可以对集合所有元素进行操作。
获得流:
List<String> items = new ArrayList<String>();
items.add("one");
items.add("two");
items.add("three");
Stream<String> stream = items.stream();
过滤流:
stream.filter( item -> item.startsWith("o") );
映射流,就是将一个值映射为另一个值:
items.stream()
.map( item -> item.toUpperCase() )
将流收集成集合:
List<String> filtered = items.stream()
.filter( item -> item.startsWith("o") )
.collect(Collectors.toList());
返回流的最大或最小值:
String shortest = items.stream()
.min(Comparator.comparing(item -> item.length()))
.get();
返回流元素的数量:
long count = items.stream()
.filter( item -> item.startsWith("t"))
.count();
将所有元素化为一个值:
String reduced2 = items.stream()
.reduce((acc, item) -> acc + " " + item)
.get();
参考
主要来自:http://tutorials.jenkov.com/java-collections/index.html
官网教程:https://docs.oracle.com/javase/tutorial/collections/index.html
集合层次结构:https://docs.oracle.com/javase/8/docs/api/java/util/package-tree.html