集合小节

  • 接口
  1. Java集合类库将接口(interface)与实现(implementation)分离。
  2. 队列通常有两种方式,循环数组(可以以任意一个点开始遍历数组元素)、链表。
  3. 循环数组是一个有界集合,容量有限。如果程序中收集的对象数量没有上限,就最好使用链表来实现。
  4. 集合的基本接口是Collection接口,Collection接口内有additeratorcontains等方法。
  5. Collection<E>接口里有个iterator()方法,该方法返回了一个实现了Iterator接口的对象,可以使用这个迭代器对象依次访问集合中的元素。Iterator接口有三个方法:next()hasNext()remove()。
  6. 使用Iterator遍历的简单方式是for…each
  7. 标准类库的所有集合都实现了Collection,而Collection扩展了Iterable接口。所以,标准类库的任何集合都可以使用for…each循环。
  • 链表
  1. 数组的中间位置删除一个元素,之后的所有元素都要向前端移动。插入一个元素也是如此(之后的元素向后移动),代价比较大。
  2. 链表将每个对象存放在独立的节点中,每个节点还存放着下一个节点的引用,并且链表都是双向链接的(存放着上、下节点的引用)。
  3. 从链表中删除一个元素,只需要更新所删除元素附近的节点即可。
  4. 链表是一个有序集合,每个对象的位置比较重要。由于迭代器是描述集合位置的,所以,依赖位置的元素的添加由迭代器来负责。
  5. 使用迭代器添加元素只针对有序集合有意义,像Set这种无序集合就没有位置可言,而这些集合都是Iterator的派生类,如果Iterator接口定义了add方法,就导致像Set这种集合也必须强制实现Iterator里的这个方法,因此,Iterator里就没有定义add方法,而把add方法定义在一个子接口ListIterator中。
  6. 链表不支持快速随机访问。如果要查看链表中第n个元素,就必须从头开始,越过n-1个元素。使用链表的唯一理由是:尽可能减少在列表中间插入或删除元素所付出的代价。如果列表中只有少数几个元素,用ArrayListOK了。如果需要对集合进行随机访问,就使用数组或者ArrayList,不要使用链表。
  • 数组链表
  1. 有两种访问元素的协议,一种是使用迭代器,一种是使用getset来随机访问。数组对于后者很管用。
  2. ArrayList封装了一个动态再分配的对象数组。
  3. VectorArrayList的区别:Vector的所有方法都是同步的,如果只有一个线程访问Vector,代码要在同步操作上浪费大量时间。
  4. ArrayList不是同步的,因此,在不需要同步时使用ArrayList。
  • 散列集
    1. 散列表可以快速查找对象。散列表为每个对象计算一个散列码(hash code)。
    2. 散列码是由对象中的实例域产生的一个整数。
    3. 不同数据域的对象产生不同的散列码。
    4. 如果自己定义类,就要负责实现这个类的hashCode方法。
    5. 自己实现的hashCode方法应该与equals兼容(a.equals(b),则ab的散列码必须相同)。
    6. Java中,散列表用链表数组实现,每个链表称为桶(bucket)。
    7. 查找表中对象的位置:先计算对象的散列码,然后与桶的总数取余。(散列码%桶的总数)
    8. 如果计算出的对象所在的桶已经满了,没法放置该对象,这就造成散列冲突(hashcollision)
    9. 这时,用新对象与桶中所有对象比较,看该对象是否已存在。
    10. 如果某个桶快要满了,就要进行再散列,创建一个更大的桶,并将所有元素插入到这个新桶中,丢弃原来的桶。
    11. HashSet实现了基于散列表的集,不关心元素的顺序时,使用HashSet


  • 树集

  1. TreeSet是个有序集合,以任意顺序将元素插入到集合中,对集合遍历时,每个值将自动按照排序后的顺序呈现。

  2. 排序是用树结构完成(如红黑树)。

  3. 需要排序使用TreeSet,不需要排序是用HashSet

  4. TreeSet如何排列元素?

    • TreeSet假定插入的元素实现了Comparable接口。

    • 如果插入自定义对象,就必须通过实现Comparable接口定义排列顺序。

    • 但是集合中的对象只能够实现这个接口一次。

    • 如果该对象在某个集合中按A方式排序,在另一个集合中按B方式排序,就没辙了。

    • 另外,需要为类的对象进行排序时,类的创建者没有实现Comparable,那也没辙。

  5. 基于上面考虑,TreeSet有了另一种排序方式:

    • Comparator接口声明了一个compare方法。

    • 如果按照A方式排序,那么就定义一个实现了Comparator接口的类。

    • 然后将这个类的对象传递给TreeSet的构造器。

  • 队列和双端队列

  1. 队列可以让人们有效的在尾部添加一个元素,在头部删除一个元素。

  2. 双端队列可以在头部、尾部同时添加或者删除元素。

  3. Deque接口由ArrayDequeLinkedList类实现。这两个类都提供了双端队列,且必要时可以增加队列长度。

  • 映射

  1. HashMapTreeMap是两个通用的实现。

  2. HashMap对键进行散列,TreeMap用键的整体排序对元素进行排序,并将其组织成搜索树。

  3. 映射表有三个视图:

  4. Set<K> keyset();    //键集合

  5. Collection<V> values();     //值集合(注意这个不是无序不重复的Set集)

  6. Set<Map.Entry<K,V>> entrySet();   //键值对集合





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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值