集合类的由来:
对象用于封装特有数据,对象多了需要存储,如果对象的个数不确定就使用集合容器进行存储。
集合特点:
1、用于存储对象的容器。
2、集合的长度是可变的。
3、集合中不可以存储基本数据类型值。
集合容器因为内部的数据结构不同,有多种具体容器。
不断的向上抽取,就形成了集合框架。
框架的顶层Collection接口:
Collection的常见方法:
1、添加。
boolean add(Object obj):
boolean addAll(Collection coll)
2、删除:
boolean remove (Object obj):
boolean removeAll(Collection coll):
void clear():
3、判断:
boolean contains(Object obj):
boolean containsAll(Collection coll):
boolean isEmpty(): 判断集合中是否有元素。
4、获取:
int size():
Iterator iterator():取出元素的方式:迭代器。
该对象必须依赖于具体容器,因为每一个容器的数据结构都不同。
所以该迭代器对象是在容器中进行内部实现的。
对于使用容器而言,具体的实现不重要,只要通过容器获取到该实现的迭代器的对象即可。
也就是Itarator方法。
Iterator 接口就是对所有的Collection 容器进行元素取出的公共接口。
其实就是抓娃娃游戏机中的夹子。
5,其他:
boolean retainAll(Collection coll); 取交集。
Object 【】 toArray(): 讲集合转成数组。
Collection
List : 有序(存入和取出的顺序一致),元素都有索引(角标),元素可以重复。
Set: 元素不能重复,无序。
1. 添加
void add(index, element);
void add (index, collection);
2. 删除;
Object remove(index):
3. 修改:
Object set (index ,element):
4 . 获取:
Object get (index):
int indexOf (object)
int lastIndexOf(object)
List subList(from, to)
list 集合是可以完成对元素的增删改查。
LinkedList
特有方法:
1. 添加: jdk 1.6以后
addFirst () offerFirst()
addLast () offerLast()
2. 获取:
getFirst () peekFirst()
getLast() peekLast
获取元素,集合的长度不改变。
如果集合中没有元素,但是该元素会被删除出集合,集合的长度会改变。
如果集合元素没有,该方法不会抛出异常,而是返回null。
List 集合子类 Vector
Vertor 已经不长用了,我们就说里面的一个方法,Elenments方法
这个方法的返回值是枚举接口,里面有两个方法,判断和获取
Vector 中提供了一个独特的取出方式,就是枚举Enumeration.
此接口Enumeration 的功能与 Iterator 接口的功能是重复的
Enumeration 的名称和方法的名称过程,书写很麻烦。
所以被Iterator 所取代,郁郁而终。
总结:
List :
Vevtor : 内部是数组数据结构,是同步的。增删,查询都很慢 100%增长
ArrayList: 内部是数组数据结构,是不同步的,增删元素的速度很快。
数组和链表的区别
当向数组中插入一个元素的时候,插入位置后面的元素都要往后一位。元素越多越慢
如果是链表的话,插入一个新元素,只需要让插入记住前一个元素的位置,
后一个元素记住插入元素的位置即可,非常简单快捷。删除也特别简单,只需要让后一个元素记住前一个元素的位置
中间的元素就删掉了。
总结:
链表:增删快,查询慢
数组:增删慢,查询快
Set:
元素不可以重复,是无序。
Set 接口中的方法和Collection 一致。
注意: Set 集合取出元素的方法只有迭代器
HashSet : 内部数据结构是哈希表,是不同步的。
如何保证该集合的元素唯一性呢?
是通过对象的hashCode 和equals 方法来完成对象唯一性的。
如果对象的hashCode值不同,那么不用判断equals 方法,就直接存储到哈希表中.
如果对象的hashCode值相同,那么不用判断equals方法,就直接存储到哈希表中。
如果为ture,视为相同元素,不存。如果为false,那么视为不同元素,就进行存储。
记住:如果元素要存储到HashSet集合中,必须覆盖hashCode方法和equals方法。
一般情况下,如果定义的类会产生很多对象,比如人,学生,书,通常都需要覆盖equals hashCode方法
建立对象判断是否相同的依据。
Set 常用的子类是HashSet和TreeSet
应用场景:假设要存储的元素必须是唯一的,这个时候就可以使用set集合。
Hashset
1:具体看下HashSet的特点
set
HashSet: 底层数据结构是哈希表。哈希表这种结构其实就是哈希值的存储。
而且每一个对象都有知己的哈希值,因为Object类中有一个hashCode方法
TreeSet
2:演示往hashset 集合中存储了两个相同的人,这是因为判断两个人是否相等的依据hashset是不知道的,所以需要我们自己定义。
再编译执行一次,发现,重复的元素还在
那么说明这里面的比较没有参考这个equals方法
在前面我们说arraylist的时候,里面的contains是参考的equals方法
3:重新思考这问题,
它判断元素唯一性的依据到底是什么呢?
看一下hashset的特点,它其实就是对哈希值的存储,他的存储是会计算元素的hash值,Object 中有一个hashcode方法
我们可以把每个对象的哈希值打印出来看一下,发现hash值都不同
从这可以看出,之前是根据hash值判断元素是否重复,现在我们的需求是根据姓名和年龄判断元素是否重复。
在这就把hashcode覆盖了,直接返回一个1,执行之后发现,打印的结果是4个,
并且发现equals方法也执行了
从这可以看出,hashset 集合保证元素唯一性,依赖的是元素的hashcode方法和equals方法
4 总结
HashSet 集合是如何保证元素的唯一性的?
HashSet集合保证元素的唯一性,依赖的是元素的hashCode方法和equals方法。
当元素的哈希值不同时,元素都有自己的独立位置。不需要再判断元素的equals方法
当元素哈希值相同时,这时元素在哈希标中位置相同,这时就需要再判断一次元素的内容是否相同,
就需要调用元素的equals 方法进行一次比较。如果equals返回是ture、那么视为两个元素为重复元素、
只存储一个
如果返回是false ,那么这两个元素不是重复元素,会存储在同一个哈希值上。
为了建立自定义对象判断元素是否重复的依据
需要覆盖hashCode方法,和equals 方法、
而且最好依据对象的特有条件来建立hashcode和equals的实现、
5 注意 其实这个时候直接把hashcode的值都返回的话,效率是比较低的,因为这后来添加的所有元素都需要和之前添加的
的元素都使用equals比较一次。因为他们的hash值相同。
可以在hashcode方法中做一个输出,验证一下。
所以我们实际应该根据对象的特征返回不同的hashcode
在这我们要根据对象的姓名和年龄进行比较。所以返回的hashcode可以这样写
注意:如果张三的姓名的hashcode和李四的年龄相等,李四的姓名的hashcode和张三的年龄相等
这样这两个人使用我们自定义的hashcode返回值也是一样的,为了避免这种情况,我们就在age
上乘以一个数都行,只要别乘1就行。定义一个常量相乘就可、
6 一般我们定义对象都会覆盖两个方法,hashcode和equals
Hashcode :建立该对象根据自身特点定义的hash值
Equals: 建立该对象内容的判断相同的依据
一般还会复写 tostring
建立该对象对应的字符窜表现形式。
hashset 细节
1 :前面的例子,判断集合中是否存在某一个元素,发现先比较hashcode。hash值重复的话在比较性名‘’
通过hashcode和equals 中做输出来验证
2 总结:
arraylist:判断包含,以及删除,都是依据元素的equals方法
hashset,判断包含,以及删除,都是依据元素的hashcode方法,当hashcode相同是,在判断一次equals方法