Java集合框架总结
目录
Java的学习一直比较零散,接下来系统的做一些总结归纳,提升自我一、思维导图?
橙色的是接口类 ,青色的是实体类
二、详解
0.java.lang.Iterable<T>
主要是实现了void forEach(Consumer<? super T> action)
方法,使得对象是可迭代的
1.java.util.Collection<E>
集合是 无序、不唯一 的,提供了一些通用的方法,常见的有:
//返回集合大小
int size();
//判断是否置空
boolean isEmpty();
//判断是否存在对象o
boolean contains(Object o);
//添加元素
boolean add(E e);
//移除元素
boolean remove(Object o);
//转换为Array
Object[] toArray();
//清除
oid clear();
//是否等于
boolean equals(Object o);
//hash值
int hashCode();
1.1.java.util.List<E>
列表是有序的,不唯一的,对于Collection,实现了一些新的方法,主要是对于index;
//在list的末尾插入元素(实现类可以选择插入的位置)
boolean add(E e);
//如果指定元素存在list中,移除list中第一次出现的指定元素(实现类可以选择具体的实现)
boolean remove(Object o);
//在指定位置插入指定集合
boolean addAll(int index, Collection<? extends E> c);
//将该列表的每个元素替换为将该运算符应用于该元素的结果。
default void replaceAll(UnaryOperator<E> operator);
//对list中的元素排列
default void sort(Comparator<? super E> c);
//删除list中的所有元素
void clear();
//根据索引获取list中的元素
E get(int index);
//用指定元素替换指定位置上的元素
E set(int index, E element);
//在指定位置上增加指定元素
void add(int index, E element);
//删除指定索引上的元素
E remove(int index);
//获取对象的第一个索引
int indexOf(Object o);
//获取对象的最后一个索引
int lastIndexOf(Object o);
//返回list的list 迭代器
ListIterator<E> listIterator();
//从指定位置返回list的迭代器
ListIterator<E> listIterator(int index);
//返回list的子list
List<E> subList(int fromIndex, int toIndex);
1.1.1.java.util.ArrayList<E>
ArrayList擅长于随机访问。同时ArrayList是非同步的。
public class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable
实现了随机访问,克隆,可序列化接口;
1.1.2.java.util.Vector<E>
Vector 可实现自动增长的对象数组,以实现类似动态数组的功能。 是线程同步的,所以说Vector是线程安全的动态数组,操作与ArrayList相似;
对于预先不知或者不愿预先定义数组大小,并且需要频繁地进行查找,插入,删除工作的情况,可以考虑使用向量类。
public class Vector<E>
extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable
1.1.3.java.util.Stack<E>
public E push(E item)//入栈
synchronized E peek()//返回栈顶元素
synchronized E pop() //出栈
synchronized int search(Object o)//查找位置,没有返回-1
boolean empty()//是否为空栈
1.1.4.java.util.LinkedList<E>
public class LinkedList<E>
extends AbstractSequentialList<E>
implements List<E>, Deque<E>, Cloneable, java.io.Serializable
不光实现了List,还实现了Deque接口,可以当作双端队列来使用,也就是说,既可以当作“栈”使用,又可以当作队列使用。
LinkedList的实现机制与ArrayList的实现机制完全不同,ArrayLiat内部以数组的形式保存集合的元素,所以随机访问集合元素有较好的性能;LinkedList内部以链表的形式保存集合中的元素,所以随机访问集合中的元素性能较差,但在插入删除元素时有较好的性能。
方法包括列表的方法,栈的方法,以及独有的
public void addFirst(E e)
public void addLast(E e)
public E getFirst()
public E getLast()
public E removeFirst()
public E removeLast()
public E peekFirst()
public E peekLast()
public E pollFirst()
public E pollLast()
public E removeFirst()
public E removeLast()
1.2.java.util.Set<E>
Set是无序的,唯一的集合,如果把两个相同元素添加到同一个Set集合,则添加操作失败,新元素不会被加入,add()方法返回false
1.2.1.java.util.HashSet<E>
HashSet不是线程同步的,如果多线程操作HashSet集合,则应通过代码来保证其同步。
集合元素值可以是null
HashSet存储原理如下:
当向HashSet集合存储一个元素时,HashSet会调用该对象的hashCode()方法得到其hashCode值,然后根据hashCode值决定该对象的存储位置。HashSet集合判断两个元素相等的标准是(1)两个对象通过equals()方法比较返回true;(2)两个对象的hashCode()方法返回值相等。因此,如果(1)和(2)有一个不满足条件,则认为这两个对象不相等,可以添加成功。如果两个对象的hashCode()方法返回值相等,但是两个对象通过equals()方法比较返回false,HashSet会以链式结构将两个对象保存在同一位置,这将导致性能下降,因此在编码时应避免出现这种情况。
HashSet查找原理如下:
基于HashSet以上的存储原理,在查找元素时,HashSet先计算元素的HashCode值(也就是调用对象的hashCode方法的返回值),然后直接到hashCode值对应的位置去取出元素即可,这就是HashSet速度很快的原因。
1.2.2.java.util.SortedSet<E>
Comparator<? super E> comparator();//自己定义比较器,对内部元素排序
E first()//第一个元素
SortedSet<E> headSet(E toElement)//e之前的元素,不包括e
E last()//最后一个元素
default Spliterator<E> spliterator()//Java8新增,生成Spliterator接口,有点类似nio里的selector
SortedSet<E> subSet(E fromElement, E toElement)//e1和e2之间的元素,包括fromElement,不包括toElement
SortedSet<E> tailSet(E fromElement)//e之后的元素,包括e#### 1.2.3.java.util.TreeSet\<E>
1.2.3.java.util.TreeSet<E>
TreeSet时SortedSet接口的实现类,TreeSet可以保证元素处于排序状态,它采用红黑树的数据结构来存储集合元素。TreeSet支持两种排序方法:自然排序和定制排序,默认采用自然排序。
♦ 自然排序
TreeSet会调用集合元素的compareTo(Object obj)方法来比较元素的大小关系,然后将元素按照升序排列,这就是自然排序。如果试图将一个对象添加到TreeSet集合中,则该对象必须实现Comparable接口,否则会抛出异常。当一个对象调用方法与另一个对象比较时,例如obj1.compareTo(obj2),如果该方法返回0,则两个对象相等;如果返回一个正数,则obj1大于obj2;如果返回一个负数,则obj1小于obj2。
Java常用类中已经实现了Comparable接口的类有以下几个:
♦ BigDecimal、BigDecimal以及所有数值型对应的包装类:按照它们对应的数值大小进行比较。
♦ Charchter:按照字符的unicode值进行比较。
♦ Boolean:true对应的包装类实例大于false对应的包装类实例。
♦ String:按照字符串中的字符的unicode值进行比较。
♦ Date、Time:后面的时间、日期比前面的时间、日期大。
对于TreeSet集合而言,它判断两个对象是否相等的标准是:两个对象通过compareTo(Object obj)方法比较是否返回0,如果返回0则相等。
♦ 定制排序
想要实现定制排序,需要在创建TreeSet集合对象时,提供一个Comparator对象与该TreeSet集合关联,由Comparator对象负责集合元素的排序逻辑。
综上:自然排序实现的是Comparable接口,定制排序实现的是Comparator接口。
3.java.lang.Map<K,V>
Map接口采用键值对Map<K,V>的存储方式,保存具有映射关系的数据,因此,Map集合里保存两组值,一组值用于保存Map里的key,另外一组值用于保存Map里的value,key和value可以是任意引用类型的数据。key值不允许重复,可以为null。如果添加key-value对时Map中已经有重复的key,则新添加的value会覆盖该key原来对应的value。常用实现类有HashMap、LinkedHashMap、TreeMap等。
3.1.1.java.util.HashMap<E>
HashMap与Hashtable是Map接口的两个典型实现,它们之间的关系完全类似于ArrayList与Vertor。HashTable是一个古老的Map实现类,它提供的方法比较繁琐,目前基本不用了,HashMap与Hashtable主要存在以下两个典型区别:
♦ HashMap是线程不安全,HashTable是线程安全的。
♦ HashMap可以使用null值最为key或value;Hashtable不允许使用null值作为key和value,如果把null放进HashTable中,将会发生空指针异常。
为了成功的在HashMap和Hashtable中存储和获取对象,用作key的对象必须实现hashCode()方法和equals()方法。
HashMap工作原理如下:
HashMap基于hashing原理,通过put()和get()方法存储和获取对象。当我们将键值对传递给put()方法时,它调用建对象的hashCode()方法来计算hashCode值,然后找到bucket位置来储存值对象。当获取对象时,通过建对象的equals()方法找到正确的键值对,然后返回对象。HashMap使用链表来解决碰撞问题,当发生碰撞了,对象将会存储在链表的下一个节点中。
3.1.2.java.util.LinkedHashMap<E>
LinkedHashMap使用双向链表来维护key-value对的次序(其实只需要考虑key的次序即可),该链表负责维护Map的迭代顺序,与插入顺序一致,因此性能比HashMap低,但在迭代访问Map里的全部元素时有较好的性能。
3.1.3.java.util.TreeMap<E>
TreeMap是SortedMap的实现类,是一个红黑树的数据结构,每个key-value对作为红黑树的一个节点。TreeMap存储key-value对时,需要根据key对节点进行排序。TreeMap也有两种排序方式:
♦ 自然排序:TreeMap的所有key必须实现Comparable接口,而且所有的key应该是同一个类的对象,否则会抛出ClassCastException。
♦ 定制排序:创建TreeMap时,传入一个Comparator对象,该对象负责对TreeMap中的所有key进行排序。
各Map实现类的性能分析
♦ HashMap通常比Hashtable(古老的线程安全的集合)要快
♦ TreeMap通常比HashMap、Hashtable要慢,因为TreeMap底层采用红黑树来管理key-value。
♦ LinkedHashMap比HashMap慢一点,因为它需要维护链表来爆出key-value的插入顺序。
3.1.4.java.util.concurrent.ConcurrentMap<E>
并发Map,提供线程安全和原子性保证
参考文章https://www.cnblogs.com/nayitian/archive/2013/09/13/3319379.html