java升级(三)集合(2)

TreeMap

TreeMap的底层是通过红黑树实现的

那么关于红黑树的概念和特性都有哪些?红黑树:又称红-黑二叉树,它首先是一颗二叉树,它具体二叉树所有的特性。同时红黑树更是一颗自平衡的排序二叉树。他的节点是红色或者黑色的平衡二叉树,它通过颜色的约束来维持着二叉树的平衡,(AVL树,它是一棵空树或它的左右两个子树的高度差的绝对值不超过1)红黑树所要有的性质是:1)节点只有黑和红两种选择且根节点必须为黑,2)每个叶结点(叶结点即指树尾端NIL指针或NULL结点)都是黑的,3)如果一个节点为红的,那么他的两个儿子都是黑的,4)对于任意结点而言,其到叶结点树尾端NIL指针的每条路径都包含相同数目的黑结点。红黑树的性质使得他的高度为logn的高度,则使得红黑树的查找、插入、删除的时间复杂度最坏为O(log n)。如下图所示,即是一颗红黑树(下图引自wikipedia:http://t.cn/hgvH1l):

树的旋转:

平衡二叉树要保持二叉树插入和删除时的平衡状态,所以就会涉及到树节点插入和删除时的旋转操作。红黑树比普通平衡二叉树要求更严格,红黑树旋转涉及到修改树中节点颜色及指针结构。

1)左旋:

2014051700004

                                    

2)右旋,

类似于左旋。

2014051700005

TreeMap:

继承AbstractMap,实现NavigableMap、Cloneable、Serializable三个接口。其中AbstractMap表明TreeMap为一个Map即支持key-value的集合。红黑树的插入和删除相当于二叉查找树的插入并在此基础上做了修复● 插入修复情况1:如果当前结点的父结点是红色且祖父结点的另一个子结点(叔叔结点)是红色。插入修复情况2:当前节点的父节点是红色,叔叔节点是黑色,当前节点是其父节点的右子。插入修复情况3:当前节点的父节点是红色,叔叔节点是黑色,当前节点是其父节点的左子。详情教你初步了解红黑树_结构之法 算法之道-CSDN博客

TreeSet

定义:

TreeSet是一个有序的提供有序的Set集合,具有Set的属性和方法,基于TreeMap实现,TreeSet中的元素支持2种排序方式:自然排序 或者 根据创建TreeSet 时提供的 Comparator 进行排序。这取决于使用的构造方法,TreeSet基础AbstractSet,实现NavigableSet支持一系列额导航方法、实现Cloneable意味着可以被克隆、实现Serializable接口,支持序列化。

构造函数:

// 默认构造函数。使用该构造函数,TreeSet中的元素按照自然排序进行排列。
TreeSet()

// 创建的TreeSet包含collection
TreeSet(Collection<? extends E> collection)

// 指定TreeSet的比较器
TreeSet(Comparator<? super E> comparator)

// 创建的TreeSet包含set
TreeSet(SortedSet<E> set)

TreeSet API

boolean                   add(E object)//将指定的元素添加到此 set(如果该元素尚未存在于 set 中)
boolean                   addAll(Collection<? extends E> collection)//将指定 collection 中的所有元素添加到此 set 中
void                      clear()                             //移除此 set 中的所有元素
Object                    clone()                             //返回 TreeSet 实例的浅表副本。属于浅拷贝
boolean                   contains(Object object)//如果此 set 包含指定的元素,则返回 true
E                         first()//返回此 set 中小于等于给定元素的最大元素不存在返回null
boolean                   isEmpty() //如果此 set 不包含任何元素,则返回 true
E                         last()    //返回此 set 中当前最后一个(最高)元素
E                         pollFirst()//获取并移除第一个(最低)元素;如果此 set 为空,则返回 null
E                         pollLast()//获取并移除最后一个(最高)元素;如果此 set 为空,则返回 null
E                         lower(E e)//返回此 set 中严格小于给定元素的最大元素;如果不存在这样的元素,则返回 null
E                         floor(E e)//返回此 set 中小于等于给定元素的最大元素;如果不存在这样的元素,则返回 null
E                         ceiling(E e)//返回此 set 中大于等于给定元素的最小元素;如果不存在这样的元素,则返回 null
E                         higher(E e)//返回此 set 中严格大于给定元素的最小元素;如果不存在这样的元素,则返回 nu
boolean                   remove(Object object)//将指定的元素从 set 中移除(如果该元素存在于此 set 中)
int                       size()//返回 set 中的元素数(set 的容量)
Comparator<? super E>     comparator()//返回元素进行排序的比较器;如果此 set 使用其元素的自然顺序,则返回 null
Iterator<E>               iterator()//
Iterator<E>               descendingIterator()//返回此 set 中所包含元素的逆序视图
SortedSet<E>              headSet(E end)//返回此 set 的部分视图,其元素严格小于 toElement
NavigableSet<E>           descendingSet()//返回此 set 中所包含元素的逆序视图
NavigableSet<E>           headSet(E end, boolean endInclusive)//返回此 set 的部分视图,其元素严格小于 toElement
SortedSet<E>              subSet(E start, E end)//返回此 set 的部分视图
NavigableSet<E>           subSet(E start, boolean startInclusive, E end, boolean endInclusive)
NavigableSet<E>           tailSet(E start, boolean startInclusive)//返回此 set 的部分视图
SortedSet<E>              tailSet(E start)

TreeSet继承关系:

java.lang.Object
   ↳     java.util.AbstractCollection<E>
         ↳     java.util.AbstractSet<E>
               ↳     java.util.TreeSet<E>

public class TreeSet<E> extends AbstractSet<E>        
    implements NavigableSet<E>, Cloneable, java.io.Serializable{}


Vector

基本概念:

Vector实现List接口,继承AbstractList类,可以将其看做队列支持相关的添加、删除、修改、遍历等功能。Vector实现RandmoAccess接口,即提供了随机访问功能,提供提供快速访问功能,Vector可以直接访问元素。Vector 实现了Cloneable接口,支持clone()方法,可以被克隆。Vector与ArrayList一样,通过数组实现的,不同的是它支持线程的同步,即某一时刻只有一个线程能够写Vector,避免多线程同时写而引起的不一致性,但实现同步需要很高的花费,因此,访问它比访问ArrayList慢。

构造函数:

Vector共有4个构造函数
// 默认构造函数
Vector()

// capacity是Vector的默认容量大小。当由于增加数据导致容量增加时,每次容量会增加一倍。
Vector(int capacity)

// capacity是Vector的默认容量大小,capacityIncrement是每次Vector容量增加时的增量值。
Vector(int capacity, int capacityIncrement)

// 创建一个包含collection的Vector
Vector(Collection<? extends E> collection)
synchronized boolean        add(E object)
             void           add(int location, E object)
synchronized boolean        addAll(Collection<? extends E> collection)
synchronized boolean        addAll(int location, Collection<? extends E> collection)
synchronized void           addElement(E object)
synchronized int            capacity()
             void           clear()
synchronized Object         clone()
             boolean        contains(Object object)
synchronized boolean        containsAll(Collection<?> collection)
synchronized void           copyInto(Object[] elements)
synchronized E              elementAt(int location)
             Enumeration<E> elements()
synchronized void           ensureCapacity(int minimumCapacity)
synchronized boolean        equals(Object object)
synchronized E              firstElement()
             E              get(int location)
synchronized int            hashCode()
synchronized int            indexOf(Object object, int location)
             int            indexOf(Object object)
synchronized void           insertElementAt(E object, int location)
synchronized boolean        isEmpty()
synchronized E              lastElement()
synchronized int            lastIndexOf(Object object, int location)
synchronized int            lastIndexOf(Object object)
synchronized E              remove(int location)
             boolean        remove(Object object)
synchronized boolean        removeAll(Collection<?> collection)
synchronized void           removeAllElements()
synchronized boolean        removeElement(Object object)
synchronized void           removeElementAt(int location)
synchronized boolean        retainAll(Collection<?> collection)
synchronized E              set(int location, E object)
synchronized void           setElementAt(E object, int location)
synchronized void           setSize(int length)
synchronized int            size()
synchronized List<E>        subList(int start, int end)
synchronized <T> T[]        toArray(T[] contents)
synchronized Object[]       toArray()
synchronized String         toString()
synchronized void           trimToSize()

Vector与Collection关系

Vector的数据结构成员变量:elementData , elementCount, capacityIncrement。
(01) elementData 是"Object[]类型的数组",它保存了添加到Vector中的元素。elementData是个动态数组,如果初始化Vector时,没指定动态数组的>大小,则使用默认大小10。随着Vector中元素的增加,Vector的容量也会动态增长,capacityIncrement是与容量增长相关的增长系数,具体的增长方式,请参考源码分析中的ensureCapacity()函数。
(02) elementCount 是动态数组的实际大小。
(03) capacityIncrement 是动态数组的增长系数。如果在创建Vector时,指定了capacityIncrement的大小;则,每次当Vector中动态数组容量增加时>,增加的大小都是capacityIncrement。
1)Vector实际上是通过一个数组去保存数据的。当我们构造Vecotr时;若使用默认构造函数,则Vector的默认容量大小是10。
2) 当Vector容量不足以容纳全部元素时,Vector的容量会增加。若容量增加系数 >0,则将容量的值增加“容量增加系数”;否则,将容量大小增加一倍。
3) Vector的克隆函数,即是将全部元素克隆到一个数组中。

数据访问:

1)通过迭代器遍历

Integer value = null;
int size = vec.size();
for (int i=0; i<size; i++) {
    value = (Integer)vec.get(i);        
}

2)随机访问

Integer value = null;
int size = vec.size();
for (int i=0; i<size; i++) {
    value = (Integer)vec.get(i);        
}

3)for循环

Integer value = null;
for (Integer integ:vec) {
    value = integ;
}

4)Enumeration遍历

Integer value = null;
Enumeration enu = vec.elements();
while (enu.hasMoreElements()) {
    value = (Integer)enu.nextElement();
}

接口关系图


CollectionCollection 层次结构中的根接口。它表示一组对象,这些对象也称为 collection 的元素。对于Collection而言,它不提供任何直接的实现,所有的实现全部由它的子类负责。
AbstractCollection提供 Collection 接口的骨干实现,以最大限度地减少了实现此接口所需的工作。对于我们而言要实现一个不可修改的 collection,只需扩展此类,并提供 iterator 和 size 方法的实现。但要实现可修改的 collection,就必须另外重写此类的 add 方法(否则,会抛出 UnsupportedOperationException),iterator 方法返回的迭代器还必须另外实现其 remove 方法。
Iterator迭代器。
ListIterator列表迭代器允许程序员按任一方向遍历列表、迭代期间修改列表并获得迭代器在列表中的当前位置。
List继承于Collection的接口。它代表着有序的队列。
AbstractListList 接口的骨干实现以最大限度地减少实现“随机访问”数据存储(如数组)支持的该接口所需的工作。
Queue队列。提供队列基本的插入、获取、检查操作。
Deque一个线性 collection,支持在两端插入和移除元素。大多数 Deque 实现对于它们能够包含的元素数没有固定限制,但此接口既支持有容量限制的双端队列,也支持没有固定大小限制的双端队列。
AbstractSequentialList提供了 List 接口的骨干实现,从而最大限度地减少了实现受“连续访问”数据存储(如链接列表)支持的此接口所需的工作。从某种意义上说,此类与在列表的列表迭代器上实现“随机访问”方法。
LinkedListList 接口的链接列表实现。它实现所有可选的列表操作。
ArrayListList 接口的大小可变数组的实现。它实现了所有可选列表操作,并允许包括 null 在内的所有元素。除了实现 List 接口外,此类还提供一些方法来操作内部用来存储列表的数组的大小。
Vector实现可增长的对象数组。与数组一样,它包含可以使用整数索引进行访问的组件
Stack后进先出(LIFO)的对象堆栈。它通过五个操作对类 Vector 进行了扩展 ,允许将向量视为堆栈。
Enumeration枚举,实现了该接口的对象,它生成一系列元素,一次生成一个。连续调用 nextElement 方法将返回一系列的连续元素。

Map接口:

Map“键值”对映射的抽象接口。该映射不包括重复的键,一个键对应一个值。
SortedMap有序的键值对接口,继承Map接口。
NavigableMap继承SortedMap,具有了针对给定搜索目标返回最接近匹配项的导航方法的接口。
AbstractMap实现了Map中的绝大部分函数接口。它减少了“Map的实现类”的重复编码。
Dictionary任何可将键映射到相应值的类的抽象父类。目前被Map接口取代
TreeMap有序散列表,实现SortedMap 接口,底层通过红黑树实现。
HashMap是基于“拉链法”实现的散列表。底层采用“数组+链表”实现。
 
WeakHashMap基于“拉链法”实现的散列表。
HashTable基于“拉链法”实现的散列表。
HashMap特点
1.    HashMap采用数组方式存储key,value构成的Entry对象,无容量限制。
2.    HashMap基于key hash寻找Entry对象存放到数组的位置,对于Hash冲突采用链表的方式来解决。
3.    HashMap在插入元素时可能要扩大数组的容量,扩大容量时对所有的数据要重新计算哈希和存放到新数组中。当元素个数size大于threshold扩容threshold = (int)(newCapacity* loadFactor);
4.    HashMap保证数组的大小为2的指数大小。
5.    HashMap非线程安全。
HashMap与Hashtable的区别HashMap从java1.2后开始引进。Hashtable从java1.0开始引入。Hashtable一开始基于继承陈旧的抽象类Dictionary实现,后面也实现了Map接口。HashMap基于Map接口实现。
HashMap允许存放key为null,value为null。对于key为null时,HashMap首先获取Entry数组中的第一个Entry对象,并基于Entry对象的next遍历链表,当找到其中Entry对象的key属性为null时,更新其value值。如果没有key属性为null的Entry,则调用addEntry(int hash, K key, V value, int bucketIndex),参数为0,null,value,0,增加一个Entry对象,增加时先获取当前数组的第一个Entry对象,记为e,然后创建一个key为null,value为传入值得得Entry对象,next为之前获取的e。数组的第一个Entry对象链表,赋为新创建的Entry对象。由此,addEntry链表倒序插入元素的。Hashtable不允许key为null或value为null,否则会抛出NullPointerException。这从put方法的源码中很容易看出来,置于为什么真么限制,不明白?
HashMap是非线程安全;Hashtable是线程安全的,其方法包含synchronized关键字实现线程安全。
HashMap的计算hash值方法如下:首先对key取其hashCode,然后通过如下计算:
h ^= (h >>> 20) ^ (h >>> 12);
        return h ^ (h >>> 7) ^ (h>>> 4);
最后取index时:return h &(length-1);
Hashtable计算hash值,直接去key的hashCode值,如下:
int hash =key.hashCode();取index时:int index = (hash& 0x7FFFFFFF) % tab.length;
HashMap和Hashtable默认构造时,默认容量值不同。
HashMap默认数组大小为16,加载因子为0.75,重新hash阈值为12.
Hashtable默认数组大小为11,加载因子为0.75,重新hash阈值为8.
HashMap和Hashtable的数组扩容方式不同。
HashMap中的数组容量大小始终保证为2的指数。重新hash,扩充容量方式为,当前容量大小*2.
Hashtable扩充容量方式为:int newCapacity = oldCapacity * 2 + 1;
一些成员方法不同。Hashtable包含一些旧的方法,如contains方法。
几乎所有通用Map都使用哈希映射技术。

哈希映射技术是一种就元素映射到数组的非常简单的技术。由于哈希映射采用的是数组结果用于确定任意键访问数组的索引机制,供一个小于数组大小的整数,该机制称之为哈希函数。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值