thingking in Java 容器深入研究

2014.10.19

But when you asked them why they didn't try it the answers tended to be "I would look silly."

但当你问他们为什么不尝试时,他们的答案往往是“这样做会很傻”。

So it's not just merely the case that in fact we are all going to die; it's a necessary truth that we're all going to die.

我们都会死去,这不仅是一个事实,还是必然的真理

If you're just spending your life floating in the scientist's lab, you're not actually accomplishing anything.

如果你只是在科学实验室里做些浅显的事,你实际上没有完成任何事情。

旅游UGC商业之路观察——蚂蜂窝案例研究专题报告

“凹凸共享租车”A轮融资近千万美金,徐小平、邵亦波力挺分享经济

传统媒体还在想转型?亚马逊早就把报纸变成了物流平台!


完整的容器分类法:


LinkedHashSet维护的是保持了插入顺序的链接列表。

可以使用工具来创建任何用于Map或Collection的生成数据集,然后通过构造器或Map.putAll()和Collection.addAll()方法来初始化Map和Collection。

享元:使得对象的一部分可以被具体化,因此,与对象中的所有事物都包含在对象内部不同。我们可以再更加高效的外部表中查找对象的一部分或整体。(或者通过某些其他节省空间的计算来产生对象的一部分或整体。

执行各种不同的添加和移除的方法在Collection接口中都是可选操作。

基本的List很容易使用:大多数时候只是调用add()添加对象,使用get()一次取出一个元素,以及调用iterator()获取用于该序列的Iterator。

如果一个对象被用于任何种类的排序容器中,那么它必须实现Comparable接口。

HashMap使用了特殊的值,称作散列码,来取代对键的缓慢搜索。散列码是相对唯一的、用以代表对象的int值,它是通过将该对象的某些信息进行转换而生成的。hashCode()是根类Object中的方法,因此所有Java对象都能产生散列码。HashMap就是使用对象的hashCode()进行快速查询的,此方法能够显著提高性能。

任何键都必须具有一个equals方法;如果键被用于散列Map,那么它必须还具有恰当的hashCode()方法;如果键被用于TreeMap,那么它必须实现Comparable。

2014.10.20

You can be passive if it isn't any good but if you are more active, you may find things.

如果没什么好处你确实可以被动点,但如果你主动些,也许会发现意外的惊喜。

Again, when you traveling around Europe, if you're lucky to do that, you'll see these big fortified towns.

如果你有幸能周游欧洲的话,你会见到那些大型的要塞城镇。

The sounds of sense are all part of language in use, which people are using to do things with.

理性的声音蕴含在所有在运用的语言中,人们利用它来处理事情

什么是网站分析?SEOer可以从三大数据进行网站分析


小米智能插座怎么样?实用吗?小米智能插座评测


正确的equals()必须满足自反性,对称性,传递性,一致性,对任何不是null的x,x.equals(null)一定返回false。

默认的Object.equals()只是比较对象的地址。因此如果要使用自己的类作为HashMap的键,必须同时重载hashCode()和equals().

hashCode()并不需要总是能够返回唯一的标识码,但是equals()方法必须严格地判断两个对象是否相同。

使用散列的目的在于:想要使用一个对象来查找另一个对象。

线性查询是最慢的查询方式。

散列用数组来表示键的信息。数组并不保存键本身,而是通过键对象生成一个数字,将其作为数组的下标。这个数字就是散列码。

为解决数组容量被固定的问题,不同的键可以产生相同的下标。所以可能会有冲突。因此不管数组多大,任何键总能在数组中找到它的位置。

于是查询一个值的过程首先是计算散列码,然后使用散列码查询数组。如果有冲突则由外部链接处理:数组并不直接保存值,而是保存值的list,然后对list的值使用equals()进行线性查询。这部分的查询自然会比较慢,但是如果散列函数好的话,数组的每个位置就只有较少的值。因此不是查询整个list,而是快速地跳到数组的某个位置,只是对很少的元素进行比较。

设计hashCode()时最重要的因素就是:无论何时,对同一个对象调用hashCode()都应该生成同样的值。

要想使hashCode()实用,它必须速度快,并且必须有意义。也就是说它必须基于对象的内容生成散列码。散列码不必是独一无二的,但是通过hashCode()和equals,必须能够完全确定对象的身份。

好的hashCode()应该产生分布均匀的散列码。

怎样写出hashCode()基本步骤:

1)给int变量result赋予某个非零值常量。

2)为对象内每个有意义的域f(即每个可以做equals()操作的域)计算出一个int散列码c

3)合并计算得到的散列码

4)返回result

5)检查hashCode()最后生成的结果,确保相同的对象有相同的散列码。

HashTable、Vector和Stack的特征是,他们是过去遗留下来的类,目的只是为了支持老的程序,最好不要在新的程序中使用他们。

在java类库中不同类型的Queue只在它们接受和产生数值的方式上有所差异。

容器之间的区别通常归结为由什么在背后支持它们。也就是说,所使用的接口是由什么样的数据结构实现的。例如HashSet是最常用的,查询速度最快;LinkedHashSet保持元素的插入次序;TreeSet基于TreeMap,生成一个总是处于排序状态的Set。

最佳的做法可能是将ArrayList作为默认首选,只有你需要额外的功能,或者当程序的性能因为经常从表中间进行插入和删除而变差的时候,才去选择LinkedList。如果使用的是固定数量的元素,那么既可以选择使用背后有数组支撑的List,也可以选择真正的数组。

对于插入操作,LinkedHashSet比HashSet的代价更高;这是由维护链表所带来额外开销造成的。

你的第一选择应该是HashMap,只有在你要求Map始终保持有序时,才需要使用TreeMap。LinkedHashMap在插入时比HashMap慢一点,因为它维护散列数据结构的同时还要维护链表(以保持插入顺序)。这是由于这个列表,使得其迭代速度更快。IdentityHashMap则具有完全不同的性能,因为它使用==而不是equals来比较元素。

只有在执行binarySearch()之前,才确实需要对List或数组进行排序。

与使用数组进行查找和排序一样,如果使用Comparator进行排序。那么binarySearch()必须使用相同的Comparator。

快速报错机制:防止多个进程同时修改同一个容器的内容。它会探查容器上的任何除了你的进程所进行的操作以外的所有变化,一旦它发现其他进程修改了容器,就会立刻抛出ConcurrentModificationException异常。

对象是可获得的,是指此对象可在程序中的某处找到。这意味着你在栈中有一个普通的引用,而它正指向此对象;也可能是你的引用指向某个对象,而那个对象含有另一个引用指向正在讨论的对象;也可能有更多的中间链接。

如果一个对象是可获得的,垃圾回收器就不能释放它,因为它仍然为你的程序所用。如果一个对象不是可获得的,那么你的程序将无法使用到它,所以将其回收是安全的。















评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值