java的集合

来源:互联网 发布:java图形界面开发教程 编辑:程序博客网 时间:2024/06/01 08:59

Iterable
  Collection
    List
      ArrayList(有序可重复,非线程安全)
      LinkedList(有序可重复,非线程安全,也实现了Queue接口)
      Vector(有序可重复,线程安全,效率低)
        Stack(有序可重复,线程安全,效率低)
    Set
      HashSet(无序不可重复,非线程安全)
        LinkedHashSet(有序不可重复,非线程安全)
      TreeSet(有序不可重复,非线程安全)
    Queue
      PriorityQueue
Map
  HashMap(无序,key不可重复,非线程安全)
    LinkedHashMap(有序,key不可重复,非线程安全)
  HashTable(无序,key不可重复,线程安全,效率低)
  TreeMap(有序,key不可重复,非线程安全)
  IdentityHashMap(无序,key可重复,非线程安全)

HashSet
  哈希表结构,内部用HashMap的实例来实现,只存放key,value是一个无用的随机对象。add(key)的过程是HashMap的put(key, 随机value对象)的过程,没有取的方法,只能由HashSet生成迭代器,迭代出内部的全部元素,实际是遍历了HashMap的Entry数组且每次只取出key。

HashMap
  哈希表结构,内部实现一个内部类Entry,看成链表结点的实现,有key,value,next等属性,内部建立一个默认长度为16的Entry数组,长度可指定。
  put(key, value)的过程是根据用户给出的key,通过哈希算法计算出一个int值,即int hash = hash(key.hashCode()),而后用hash与表长取余,实际得到了Entry数组的下标,而后判断下标处的值,若没有值则根据用户给出的key、value创建一个Entry对象存入该位置,若有值则将用户给的key与该Entry的key对比,若相同由于key不可重复,用用户给的value替换当前Entry的value,若不同根据当前Entry的next,将用户给的key与next指向的下一个Entry的key继续比较,若找到相同的同上,若未找到相同的则创建新的Entry对象,并使用单链表的头插法插入新的结点;get(key)的过程是首先根据key生成哈希地址,然后到地址处比较key,若相同返回对应的value,若不同返回null。
  由于key不可重复,在插入元素时有一个key的比较过程,使用equals方法。该方法默认比较的是对象的引用,除了java已经覆写过equals方法的类外,其它的类做key都必须先覆写equals方法,保证比较的是对象的内容而非引用。同理hashCode方法默认是根据对象的引用生成而非内容,如两个内容相同但引用不同的对象,被看成是相同的key,但很可能产生不同的hashCode,连对比key的可能都没有。由此重写equals与重写hashCode是一起的。String的equals与hashCode都已被重写。一切取决于字符串的内容,而不再是对象的引用,通常用String类型作为key。
  当哈希表的长度不够时要对其扩大,HashMap哈希表长度默认为16,最大长度为2的30次方,扩充因子为0.75f。当哈希表中元素个数 >= 哈希表的长度 * 0.75f时,会自动将表长度扩大为当前表长的一倍。由于每次扩容都要重新计算表内已存元素的位置导致影响性能,由此应尽量避免扩容,在定义HashMap时尽量不要使用默认的长度。
  备注:
  1、在重写对象的hashCode时,必须以该对象的某个不会被改变的属性为基准,否则对象的属性改变,hashCode值也会改变,会出现前后不一致的现象。
  2、equals只能用于对象,默认比较的是引用。java规范建议重写对象的equals方法,使其用于比较对象的内容。==是java的关系运算符,引用类型比较的是引用,基本类型比较的是值。
  3、key、value均可为null,key为null时不调用hash方法,直接存在Entry下标为0的位置。由于key不可重复,所有的键值对中只可能有一个key = null的键值对,但可有多个value = null的键值对。

原创粉丝点击