Thinking in Java:容器深入研究
1.虚线框表示Abstract类,图中大量的类的名字都是以Abstract开头的,它们仅仅是部分实现了特定接口的工具,因此创建时能够选择从Abstract继承。
Collections中的实用方法:挑几个经常使用的:
1. reverse(List):逆转次序
2. rotate(List,int distance)全部元素向后移动distance个位置,将末尾元素循环到前面来(用了三次reverse)
3.sort(List,Comparator) 排序,可依照自己的Comparator
4.copy(List dest,List src) 复制元素(引用)
5.fill(List,T x)同Arrays一样。复制的是同一引用
6.disjoint(Collection。Collection) 两个集合没有不论什么元素时返回ture
7.frequency(Collection, Object x)返回Collection中等于x的元素个数
8.binarySearch()折半查找(要求有序)
Collection的功能方法:
boolean add(T) 可选方法。若没将參数加入进容器,则false
boolean addAll(Collection )可选方法,仅仅要加入了随意元素就true
void clear() 可选方法
boolean contains(T) 若容器中已经持有具有泛型T參数。true
Boolean containsAll(Collection )
boolean isEmpty()
Iterator iterator()
Boolean remove(Object) 可选方法
boolean removeAll(Collection) 可选方法
Boolean retainAll(Collection) 容器交集,可选方法
int size()
Object[] toArray()
T[] toArray(T[] a)返回包括容器中全部元素的数组
PS:这里不包括随机訪问所选择元素的get()方法,由于Collection包括Set。而Set是自己维护内部顺序的(这使得随机訪问变得没有意义)
2上述执行各种不同的加入和移出的方法在Collection接口中都是可选操作,意味着实现类并不须要为这些方法提供功能定义
未获得支持的操作
1.Arrays.asList()会生成一个List,它基于一个固定大小的数组。仅支持哪些不会改变数组大小的操作,不论什么会引起对底层数据结构的尺寸进行改动的方法都会产生一个UnsupportedOperationException异常(这里Arrays.asList返回的是List的代理类)。若想生成循序使用全部的方法的普通容器,能够将其作为參数传入到新的容器中(如addAll,或构造器等)
2Collections类中的“不可改动”方法(unmodified*方法)将容器包装到了一个代理中,该代理类不支持不论什么试图改动容器的操作
Set和存储顺序:
1:Set(interface):加入Set的元素必须定义equals()方法以确保对象的唯一性,Set接口不保证维护元素的次序
2:HashSet:存入HashSet的元素必须定义hashCode()
3:TreeSet:保证有序,元素必须实现Comparable接口
4:LinkedHashSet 具有HashSet的查询速度,且内部使用链表维护元素的顺序,元素必须定义hashCode()
尽管hashCode不是必须实现的。可是对于良好的编程风格而言,应该在覆盖equals方法时,总是同一时候覆盖hashCode()方法。
3.假设一个对象被用于不论什么种类的排序容器中。如SortedSet(TreeSet是其唯一实现),则其必须实现Comparable接口
PS:在接口的实现方法compareTo()中,不应该使用return i-i2这种形式,错误编程。由于这样没有考虑到i-i2数值溢出的问题,应该
return (arg.i < i ?
-1 : (arg.i == i ? 0 : 1))
4若在HashSet容器中元素并没有又一次定义hashCode(),将它们放置到不论什么散列实现中都可能会产生反复值,这甚至不会产生执行时错误。
唯一的可靠方法就是写单測。
5.SortedSet的意思为“依照对象的比較函数对元素排序”,而不是“元素插入的次序”。
6.优先级队列。其元素排序顺序也是通过实现Comparable而进行控制的。
理解Map:
1:HashMap : 基于散列表的实现。
能够通过构造器设置容量和负载因子调整容器性能。
2:LinkedHashMap :与HashMap却别在于迭代遍历时。取得键值对顺序是插入次序。或是LRU次序。除了迭代訪问时其余性能要慢一点
3:TreeMap:基于红黑树的实现。查看“键”或者“键值对”的时候,它们会被排序(依照Comparable方法),其唯一的带有subMap()方法的Map,能够返回一个子树。
4:WeakHashMap:弱键映射。同意释放映射所指向的对象;假设映射之外没有引用指向某个“键”,则此键能够被垃圾收集器回收
5:IdentityHashMap:使用==取代equals()对”键“进行比較的散列映射
PS:不论什么键都必须具有一个equals方法。假设键被用于散列Map。则还必须有一个恰当的hashCode方法。若键被用于TreeMap,则它必须实现Comparable
7.map中能够直接打印values方法的结果,该方法会产生一个包括Map中全部值得Collection。由于这些Collection背后是由Map支持的,所以对Collection的不论什么改动都会反映到与之相关联的Map。
8.LinkedHashMap散列化全部的元素,可是在遍历键值对时,却又以元素的插入顺序返回键值对。此外,能够在构造器中设定LinkedHashMap,使之採用基于訪问的LRU算法,于是没有被訪问过的元素就会出如今队列的前面。对于须要定期清理元素以节省空间的程序来说,此功能使得程序非常easy得以实现。
散列与散列码:
1.Object的hashCode()方法生成散列码,而它默认是使用对象的地址计算散列码。
2.可能你会觉得,仅仅需编写恰当的hashCode()方法的覆盖版本号就可以。可是它仍然无法正常执行,除非你同一时候覆盖equals()方法。他也是Object的一部分。
HashMap使用equals()推断当前的键是否与表中存在的键同样。
PS:正确的equals()方法必须满足下列5个条件:
1)自反性:x.equals(x)一定返回true
2)对称性:x.equals(y)返回true当且仅当y.equals(x)
3)传递性:x.equals(y)且y.equals(z)。则x.equals(z)为true
4)一致性:若x.equals(y)返回true,则不改变x,y时多次调用x.equals(y)都返回true
5)对于随意的非空引用值x。x.equals(null)一定返回false。
为了速度而散列:
1.由于瓶颈位于键的查询速度。因此解决方式之中的一个就是保持键的排序状态,然后使用Collections。binarySearch()进行查询
2.散列则更进一步,它将键保存在某处,以便能够非常快找到。
存储一组元素最快的数据结构是数组。所以使用它来表示键的信息。信息就是散列码。
3.通常。冲突由外部链接处理,数组并直接保存至,而是保存值得list,然后对list中的值使用equals方法进行线性查询。
4.进来,Java的散列函数都使用2的整数次方。
对现代的处理器来说,除法与求余数是最慢的操作。使用2的整数次方长度的散列表,可用掩码取代除法。由于get是使用最多的操作。求余数的%操作是其开销最大的部分。而是用2的整数次方能够消除此开销。
9.设计hashCode()时最重要的因素就是:不管何时。对同一个对象调用hashCode()都应该生成同样的值。
若你的hashCode()方法依赖于对象中易变的数据,用户就要当心了。
同一时候,也不应该使hashCode()依赖于具有唯一性的对象信息,尤其是使用this的值,这仅仅能产生非常糟糕的hashCode()由于这样无法生成一个新的键使之与put中原始的键值对中的键同样。
10.要想使hashCode使用。他必须速度快,而且有意义,也就是说,他必须基于对象的内容生成散列码。
散列码不必是独一无二的。可是通过hashCode()和equals,必须能够全然确定对象的身份。
性能:
1.应该避免使用Vector(能正常工作的唯一原因,仅仅是为了向前兼容,被适配成了List)
2TreeSet迭代通常比用HashSet要快。另外。对于插入操作,LinkedHashSet比HashSet代价更高,这是由维护链表所带来额外的开销造成的
3.Hashtable的性能大体上与HashMap相当。
由于HashMap是用来替代Hashtable的。
因此它们使用了同样的底层存储和查找机制。
4.IdentityHashMap则具有全然不同的性能,由于它使用==而不是equals来比較元素。
HashMap的性能因子:
容量:表中桶位数(slot)
初始容量:表在创建时所拥有的桶位数。HashMap和HashSet都具有同意你仅仅能初始容量的构造器。
尺寸:表中当前存储的项数。
负载因子:尺寸/容量。
HashMap和HashSet都具有同意你指定负载因子的构造器。表示负载情况达到该负载因子的水平时,容器将自己主动加入其容量(桶位数)。实现方式是使容量大致加倍,并又一次将现有对象分布到新的桶位数集中(这被称为再散列)
Collection或Map的同步控制:
1.Collections类有办法能够自己主动同步整个容器。其语法与“unmodified*”类似。
List a = Collections.synchronizedList(new ArrayList(data));
最好如上所看到的,是直接将新生成的容器传递给了适当的“同步”方法。这样做就不会有不论什么机会会暴漏出不同步的版本号。
高速报错:
Java容器有一种保护机制,能够防止多个进程同一时候改动同一个容器的内容。Java容器类类库採用高速报错(fail fast)机制。
它会探查容器上的不论什么除了你的进程所进行的操作以外的全部变化,一旦发现其它进程改变了容器,就会立马抛出ConcurrentModificationException异常。如:在容器取得迭代器之后,又有东西呗放入到了该容器中
ConcurrentHashMap,CopyOnWriteArrayList、CopyOnWriteArraySet都使用了能够避免ConcurrentModificationException的技术
持有引用:
1.java.lang.ref类库包括一组类。当存在可能会耗尽内存的大对象的时候,这些类显得特别实用。有SoftReference、WeakReference、PhantomReference。
当垃圾回收期正在考察的对象仅仅能通过某个Reference对象才“可获得时”,上述这些不同的派生类为垃圾回收器提供了不同级别的间接性指示
2.假设想继续持有对某个对象的引用。希望以后还能够訪问到该对象。可是也希望能够同意垃圾回收器释放它,这时就应该使用Reference对象。这样,你能够继续使用对象,而在内存消耗殆尽的时候又同意释放该对象。
3.以Reference对象作为你和普通引用之间的媒介(代理),另外一定不能有普通的引用指向那个对象。这样就能达到上述目的
4.对于SoftReference、WeakReference、PhantomReference三个引用的差别和功能,详见JVM.
5.使用SoftReference、WeakReference时,能够选择是否要将它们放入ReferenceQueue(用作“回收前清理工作”的工具,见JVM)。而PhantomReference仅仅能依赖于ReferenceQueue。
6.WeakHashMap:见JVM。它被用来保存WeakReference。这该映射中,每一个值仅仅保存一份实例以节省存储空间。且WeakHashMap同意垃圾回收器自己主动清理键和值。所以它显得十分便利。
Java 1.0/1.1容器(了解):
1.Enmuberation:老版本号的迭代器。其接口比Iterator小,可是不管怎样代码中应该尽量使用Iterator。能够通过使用Collections.enumeration()方法来从Collection生成一个Enumeration
2.Hashtable:如前所说,主要的Hashtable与HashMap非常类似。
尽量使用HashMap(多线程同步时仍然有非常多其它的选择)
3.BisSet:假设想要高效率地存储大量“开/关”信息,BitSet是非常好的选择。只是它的效率仅是对空间而言。假设须要高效訪问时间,BitSet比本地数组稍慢一些,BitSet最小容量是Long:64位,若存储的内容比較小,如8位。则BitSet浪费了一些空间。BitSet也会想普通容器一样随着元素的加入而扩充其容量。总的来说。若拥有一个能够命名的标志集合。那么EnumSet一般是一种更好的选择,由于EnumSet同意你依照名字而不是数字位的位置进行操作,因此能够降低错误。
Thinking in Java:容器深入研究的更多相关文章
- 《Java编程思想》笔记 第十七章 容器深入研究
1 容器分类 容器分为Collection集合类,和Map键值对类2种 使用最多的就是第三层的容器类,其实在第三层之上还有一层Abstract 抽象类,如果要实现自己的集合类,可以继承Abstract ...
- Java编程思想之十七 容器深入研究
17.1 完整的容器分类方法 17.2 填充容器 import java.util.*; class StringAddress { private String s; public StringAd ...
- Java容器解析系列(0) 开篇
最近刚好学习完成数据结构与算法相关内容: Data-Structures-and-Algorithm-Analysis 想结合Java中的容器类加深一下理解,因为之前对Java的容器类理解不是很深刻, ...
- 【Java心得总结七】Java容器下——Map
我将容器类库自己平时编程及看书的感受总结成了三篇博文,前两篇分别是:[Java心得总结五]Java容器上——容器初探和[Java心得总结六]Java容器中——Collection,第一篇从宏观整体的角 ...
- 【Java心得总结六】Java容器中——Collection
在[Java心得总结五]Java容器上——容器初探这篇博文中,我对Java容器类库从一个整体的偏向于宏观的角度初步认识了Java容器类库.而在这篇博文中,我想着重对容器类库中的Collection容器 ...
- 【Java心得总结五】Java容器上——容器初探
在数学中我们有集合的概念,所谓的一个集合,就是将数个对象归类而分成为一个或数个形态各异的大小整体. 一般来讲,集合是具有某种特性的事物的整体,或是一些确认对象的汇集.构成集合的事物或对象称作元素或是成 ...
- Java 容器(list, set, map)
java容器类库的简化图: (虚线框表示接口, 实线框表示普通的类, 空心箭头表示特定的类实现了接口, 实心箭头表示某个类可以生成箭头所指的类对象) 继承Collection的主要有Set 和 Lis ...
- Java - 容器详解
一.ArrayList 长度可变数组,类似于c++ STL中的vector. 元素以线性方式连续存储,内部允许存放重复元素. 允许对元素进行随机的快速访问,但是向ArrayList中插入和删除元素的速 ...
- Java 容器:Collection 初探之 List
1 ///: JavaBasic//com.cnblogs.pattywgm.day1//CollectionTest.java 2 3 package com.cnblogs.pattywgm.da ...
随机推荐
- python 11:range(起始索引,终止索引,步数)(默认情况下步数为1,生成从起始索引,每次增加(终止索引-起始索引)/步数,到终止索引前的数字串)
squares = [] for value in range(1,11): #第三参数默认为1,生成从1开始,每次增加1步数,到11前的10为止的数字串 square = value ** 2 sq ...
- Redis学习笔记(四)-数据类型之list类型
redis的list类型其实就是一个每个子元素都是string类型的双向链表.所以[lr]push和[lr]pop命令的算法时间复杂度都是O(1).另外list会记录链表的长度.所以llen操作也是O ...
- 富文本wangEditor的批量激活
最近项目中使用了wangEditor这个轻量级的富文本框,由于需求是一个页面中会有多个富文本框同时激活,所以写了个批量激活的jquery方法,分享一下 // 激活富文本框 var wangEditor ...
- ★Java语法(二)——————————数据类型常见问题
1.用float型定义变量:float a = 3.14 :是否正确? 不正确.“=” 两边的精度类型不匹配,应为:float a =(float)3.14 或 float a =3.14F 或 ...
- Deutsch lernen (15)
1. unterscheiden - unterschied - unterschieden 区别,区分:(能够)分清 Die beiden Begriffe sind nur schwer ...
- QT设计UI:QT模式对话框打开文件
使用QT模式对话框,并使显示框 为背景色: 方法使用了QCheckBox *native; #include <QCheckBox> 初始化函数代码: //设置默认打开图像位置 nat ...
- 【sqli-labs】 less27 GET- Error based -All you Union&Select Belong to us -String -Single quote(GET型基于错误的去除了Union和Select的单引号字符型注入)
看一下过滤函数 看一下/s是什么东西 那直接通过大小写就可以绕过了 http://192.168.136.128/sqli-labs-master/Less-27/?id=0'%a0uNion%a0s ...
- Centos6.6 安装Subversion服务
一.介绍 Subversion 简称就是svn服务器,用来托管代码的,类似的还有git 1)Centos6.6 2)Subversion 二.安装 yum -y install subversion ...
- mac nwjs入门
NW.js由node-webkit项目发展而来其实很多东西官网上都有.但是鉴于搜索引擎(百度,google)搜索到的相关文章,让人看的很不明白.所以决定写下此篇文章. 官网:https://nwjs. ...
- vue中需要注意的问题总结(上)
React 与其说是一种框架,倒不如说是一种开发范式.它的核心理念非常简单: 界面/视图就是数据结构的可视化表达UI = f(data) 而界面/视图由组件组合而来UI = f1(data) + f2 ...