第十七章:容器深入研究

填充容器

  1. new ArrayList<Object>(Collections.nCopies(size, item))和Collections.fill(list, item)
  2. 一种Generator解决方案
    所有Collection子类型都有一个接收另一个Collection对象的构造器,用所接收的Collection对象中的元素来填充新的容器。或者使用Collection.addAll(Generator)。
//适配器模式的实例
public class CollectionData<T> extends ArrayList<T>{
  public CollectionData(Generator<T> gen, int quantity){
    for(int i = 0; i< quantity; i++){
      add(gen.next());
    }
  }
  
  //a generic convenience method;
  public static <T> CollectionData<T> list(Generator<T> gen, int quantity){
    return new CollectionData<T>(gen, quantity);
  }
}
  1. Map生成器:
    Map可以使用相同方式,但需要一个Pair类。然后使用Generator<Pair<K,V>>的对象填充map。
public class Pair<K,V>{
  public final K key;
  public final V value;
  public Pair(K k, V v){
    key = k;
    value = v;
  }
}
  1. 使用Abstract类
    **享元模式:采用一个共享来避免大量拥有相同内容对象的开销。这种开销中最常见、直观的就是内存的损耗。享元模式以共享的方式高效的支持大量的细粒度对象。java的String对象的创建就是享元模式。
    为了创建只读的Map,可以继承AbstractMap并实现entrySet(),为了创建只读的Set,可以继承AbstractSet并实现iterator()和size()。享元在于子类只存储索引,通过索引读取内容。

可选操作

执行各种不同的添加和移除的方法在Collection都是可选操作,如果调用没有实现的方法,会抛出UnsupportedOperationException。这是为了防止接口爆炸。
最常见的未获支持的操作,都来源于背后由固定尺寸的数据结构支持的容器,比如Arrays.asList()将数组转换为List时,就会得到这样的容器,或者Collections.unmodifiableList()返回的容器。所以,应该把这种结果作为构造器参数传递给任何Collection,这样就可以产生尺寸可调整的容器。

Set和存储顺序

Set(interface) 存入Set的每个元素都必须是唯一的,加入Set的元素必须定义equals()方法以确保对象的唯一性。Set与Collection有完全一样的接口,Set不保证维护元素的次序。
HashSet(默认) 为快速查找而设计的Set。存入HashSet的元素必须定义hashCode()
TreeSet 保存次序的Set,底层为树结构。使用它可以从Set中提取有序的序列。元素必须实现Comparable接口
LinkedHashSet 具有HashSet的查询速度,且内部使用链表维护元素的顺序(插入的顺序)。bianlishi,以插入顺序显示。元素也必须定义hashCode()方法。

对于良好的编程风格来说,你应该在覆盖equals()方法时,总是同时覆盖hashCode()方法。
SortedSet接口:比如TreeSet就是其中一个实现。

队列

Queue接口两个实现是LinkedList和PriorityQueue,差异在于排序行为而不是性能。
优先级队列:优先级队列的元素需要实现Comparable。
双向队列:可以在任何一段添加或移除元素。LinkedList包含支持双向队列的方法,但是java标准库中没有这样的接口。

Map

  1. 性能:
    HashMap使用散列码——“相对唯一”来代表对象的int值。如果不能满足你的要求,可以创建自己的Map来进一步提高查询速度。
HashMap* 基于散列表实现,插入和查询“键值对”的开销是固定的。可以通过构造器设置容量和负载因子,以调整容器的性能。
LinkedHashMap 取得键值对是插入顺序,或是最近很少使用(LRU)顺序。只比HashMap慢一点,迭代访问时更快,因为使用链表维护内部次序。以插入顺序返回键值对迭代遍历。
TreeMap 基于红黑树的实现。查看键或键值对时,它们会被排序(次序有Comparable或Comparator决定)。得到结果是经过排序的。唯一带有subMap()的Map,可以返回一个子树。
WeakHashMap 弱键映射,允许释放映射所指向的对象。如果映射之外没有引用指向某个键,该键可以被垃圾回收。
ConcurrentHashMap 线程安全的Map,不设计同步加锁。
IndentityHashMap 使用==代替equals()对键进行比较的散列映射。专为特殊问题设计

*任何键都必须具有equals()方法。
*SortedMap接口:TreeMap是其唯一实现。

散列与散列码

HashMap使用equals()判断当前的建是否与表中存在的键相同。
HashMap的性能因子:

  1. 容量:表中的桶位数
  2. 初始容量:表在创建时所拥有的桶位数。HashMap和HashSet都具有允许你指定初始容量的构造器。
  3. 尺寸:表中当前存储的项数
  4. 负载因子:尺寸/容量。空表的负载因子为0,班满表的负载因子是0.5,负载轻的表产生冲突的可能性小,因此对于插入和查找都是最理想的,但会减慢使用迭代器遍历的过程。HashMap和HashSet都具有允许你指定负载因子的构造器,表示当负载情况达到该负载因子的水平时,容器将自动增加其容量(容量),实现方式是使容量加大一倍,并重新将现有对象分布到新的桶位几种(再散列)。

Collections有用的api

快速报错

java容器有一种保护机制,当你调用iterator()获取迭代器后,再想迭代器所指向的Collection添加点什么,就会抛出ConcurrentModificationException异常。

持有引用

如果想继续持有对某个对象的引用,希望以后还能够访问到该对象,但是也希望能够允许垃圾回收器释放它,这是就应该使用Reference对象。一般是以Reference对象作为你和普通引用之间的媒介(代理),另外一定不能有普通的引用指向那个对象。
Reference抽象类的导出类:SoftReference(内存敏感的高速缓存),WeekReference(目的是“规范映射”,不妨碍垃圾回收器回收映射的键或值,“规范映射”中对象的实例可以在程序的多处被同时使用,以节省存储空间),PhantomReference(调度回收前的清理工作,比Java终止机制灵活),由强到弱排列,对应不同级别的可获得性。PhantomReference只能放入ReferenceQueue,其余两者可选。
补充资料1
补充资料2

Java 1.0/1.1 的容器

  1. Vector:自我扩展的序列=>ArrayList
  2. Enumeration:接口,hasMoreElements()、nextElement()。
  3. HashTable => HashMap
  4. Stack:继承Vector
  5. BitSet:高效率的存储大量“开/关”信息,最小容量为long:64位,自动扩容(都是64的倍数),若存储的内容比较小,就浪费了一些空间。补充
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 225,498评论 6 524
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 96,668评论 3 406
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 172,857评论 0 370
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 61,305评论 1 303
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 70,308评论 6 401
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 53,747评论 1 316
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 42,078评论 3 431
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 41,080评论 0 280
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 47,649评论 1 327
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 39,644评论 3 347
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 41,760评论 1 355
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 37,352评论 5 351
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 43,076评论 3 341
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 33,490评论 0 25
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 34,651评论 1 277
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 50,353评论 3 383
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 46,828评论 2 367

推荐阅读更多精彩内容