P264 HashSet集合介绍
Set接口:
- extends Collection
- 不包含重复元素
- 没有索引
- 不能使用普通for遍历
HashSet类:
- implements Set
- 底层:哈希表===》查询速度很快!
- 不包含重复元素
-
【当add进重复元素时,第二次那个会默认不存进去】
- 没有索引
- 不能使用普通for遍历
-
用迭代器/增强for遍历
//迭代器
Iterator<Integer>it=set.iterator();
while(it.hasNext()){
Integer n=it.next();
sout(n);
}
//增强for循环
for(Integer i:set){
sout(i);
}
- 无序集合,存储/取出顺序可能不一样
-
按123add进去,取出来不一定是123
Hash值
哈希值:
- 一个10进制的整数,由系统随机给出
- 对象的地址值(逻辑地址,模拟出来得到地址)不是数据实际存储的物理地址
- 获取对象的哈希值:
-
int hashCode()
-
可以重写,例如使地址都为1
-
此时若判断p1==p2,也是false(物理地址不一样
P266 hashset集合存储数据的结构(哈希表)
- 哈希表=数组+链表/数组+红黑树(提高查询的速度)
- 哈希表特点:速度快
P267
set集合再调用add方法时,add方法会调用元素的hashCode方法和equals方法,判断元素是否重复
add方法的实现步骤
认定相同:哈希值相同+equals方法返回true===》不会存进集合中
认定不同:哈希值不同+equals方法返回false===》会存进集合中
P268 hashset存储自定义类型元素
integer和string等预先定义好的类都重写了hashcode和equals方法,以可以判断hash值是否相同/能否存储进去某个位置
现在想存储自定义类型元素:
//创建hashset集合存储person类对象
HashSet<Person>set=new HashSet<>();
Person p1=new Person("a",1);
Person p2=new Person("a",1);
sout(p1.hashCode());
sout(p2.hashCode());//重写前hashcode不一样,重写后hashcode一样
sout(p1==p2);//重写前false,重写后false(==比较地址值
sout(p1.equals(p2));//重写前false,重写后true(正确判断了两个值是否相等)
TIPS关于==和equals
1、没有重写equals()方法的类中,调用equals()方法其实和使用==号的效果一样,也是比较的地址值
2、equals重写后:比较两个内容(值/字符串等)是否相同
3、Object类的equals()方法代码如下:
public boolean equals(Object obj) {
return (this == obj);
}
P269 hashset下的LinkedHashSet
具有可预知迭代顺序的set接口的哈希表和链接列表实现
与hashset区别:此维护着一个运行于所有条目的双重链接列表
此链接列表定义了迭代顺序
linkedhashset extends hashset
底层是一个哈希表(数组+链表/红黑树)+链表:多了一条链表—》记录元素存储顺序
hashset存储,有序且不允许重复
P270 可变参数
什么时候用
一个方法需要多个参数,可以进行简化👇
使用前提
类型确定,个数不确定
格式
数据类型…变量名
原理
底层—》数组,创建不同长度的数组用来存储
个数可以为0,1,2…多个
定义计算0-n个整数和的方法
//可变参数,jdk1.5后新特性
//定义计算0-n个整数和的方法
public static int add(int...arr){//arr数组名
sout(arr);//输出一个数组的地址
//如何累加求和
//遍历数组,获取数组中的每一个元素
int sum=0;
for(int i:arr){
sum+=i;
}
return sum;//把求和结果返回
}
public static void main(String[]args){
int i=add(10);//传入一个参数==》arr是1个长度为1的数组
int i=add(1,2,3,4,5,6,7);//传入7个参数==》arr是一个长度为7的数组
}
好处:
- 【方法处】可以不设置有多少个加数
- 由【实际main】中执行时【决定】
注意事项: