17、
ArrayList的默认大小是10,和Vector一样。
18、哈希算法的出现提高了查询的效率,但是缺点是元素对象不能重复。
在set接口(其方法和Collection的方法一样)中,有一个实现set接口的子集类是HashSet(),其元素对象存放的角标是由特定的哈希算法来确定的。例如下图所示
19、上面讲的是存入的是字符串对象,因为传入的是字符串,而String类自己的hashCode()方法和equals()已经覆盖重写了继承自Object类的hashCode()方法和equals()方法。所以在判断存入的数据是否是重复的时候,先判断数据的hashCode是否一样,不一样就存在不同的地方,如果一样,就要进一步用equals()方法来判断内容是否一样,如果连内容都一样,那就不存了,如果内容不一样,还是会存的,譬如上图中的挂着。
但是当我们传入Person类的对象时,如果事先定义的Person类内部没有覆盖重写继承自Object类的hashCode()和equals()方法,那么存Person对象是哈希地址的生成和equals的判断就是用的Object对象所固有的,而Object对象的哈希值和equals都是判断的对象的地址,由于每new一个对象,它的引用地址都不同,所以判断方法就会把相同内容的对象也判为不同的对象。
想修正这个问题就要先覆盖重写Person类中的hashCode()方法和equals()方法,equals()方法改写为判断名字和年龄是否相同。
age*38是想让hash值足够大,这样一般就不会冲突,就不需要进一步用equals()方法来判断内容是否一致,equals判断使得效率变低。
对于ArrayList这样的判断集合中是否有这个元素对象,关键在于用equals方法判断是否相同,而对于HashSet这样的集合,则是用hash值和equals一起判断是否相同。
21、之前说List是有序的,Set是无序的,其子类HashSet虽然是无序的,但是HashSet的子类LinkedHashSet确实有序的,它和List的区别在于:List的是元素对象有序不唯一,而LinkedHashSet的元素对象是有序唯一的,两者的区别就在于是否元素对象唯一!!!
注意我们说的有序是指:存元素对象时的顺序和取元素对象时的顺序完全一样!!!
22、TreeSet的默认排序是按自然顺序(字典顺序)来存元素对象的。排序就必然要比较,存一个不用比,存两个就需要比一下顺序了。当实现了Comparable接口后就具有比较大小的能力了。所以把Person类实现comparable接口就行了。
上图中的比较方法需要实现Comparable接口后,覆盖重写里面的compareTo()方法后就具有了比较的能力。
23、TreeSet之所以在存放元素对象的时候具有存放排序的功能,第一是要求元素具有比较的功能也就是元素对象实现了Comparable接口,并覆盖重写了里面的compareTo()方法。第二就是给TreeSet集合制定一个比较器即实现了Comparator接口的子类,覆盖了接口中的compare方法,同时将该类对象作为参数传递给TreeSet集合的构造函数。
24、首先要搞清楚java中有序和无序的概念
有序指的是存储顺序与添加顺序相同,并且可以通过下标访问,List就是这样。
无序刚好相反,指的是存储顺序与添加顺序无关,没有下标,当然也不可能通过下标访问,Set就是如此。
这里需要注意的是,有序、无序中的“序”与我们平常所说的“顺序”无关。
而TreeSet是无序,但又是排好序的。即添加顺序与存储顺序无关,但是其中的对象实现了排序。
TreeSet在内存中存储的原理:基本就是树的结构,通过比较器返回的比值的正负来确定是存在左子树还是右子树,但是这样并非是真正的有序--怎样的顺序存入怎样的书序取出。譬如上图中我们用迭代器来取出TreeSet中的元素,得到的顺序是按(比较规则)升序的结果来输出的,21,25,28,两个29就w在前,z在后。如果想变成真正的有序,可以将每一次比较的返回值固定的为1,这样每次存进去的元素对象都在上一个元素的右边(也就是比上一个大),输出的是升序,刚好好存入的顺序一样,也就相当于是真正的有序了。如果比较器返回值固定设为-1,那么迭代器的输出相当于逆序输出。
要是设为返回0,那么就只能存进去一个元素对象。
25、练习:对字符串进行长度排序
只需把TreeSet中的比较器的compare方法改成比较成都即可,此时依靠元素对象实现Comparable接口的第一种排序比较方法已不好用,因为String的比较方法是java固定的自带,没法改变。只好用第二种构建比较器,屏蔽了他自身带的比较方法。
上图也证明了TreeSet在迭代输出时是按升序(什么是升序,就是根据compare的判断规则返回正负来确定的)来输出的,其实也就是在存的时候由比较规则得到元素对象已经是升序的了,只需从第一个迭代到最后一个。