目录
1、Set接口简介
一个不包含重复元素的集合;
此接口没有索引,没有带索引的方法;
set接口跟Collection方法基本一致,主要研究其实现类;
2、HashSet
简介
此类实现set接口,由哈希表(实际上是一个HashMap实例)支持;
它不保证set的迭代顺序,特别是不保证该顺序恒久不变;
允许使用null元素;
此实现不是同步的(多线程,速度快);
特点
一个不包含重复元素的集合;
此接口没有索引,没有带索引的方法;
无序的集合,存取元素的顺序可能不一致;
底层是一个HashMap结构(查询速度快);
//多态方式实现HashSet
Set<Integer> set = new HashSet<>();
set.add(7);
set.add(1);
set.add(4);
set.add(4);//不允许存储重复的数据,编译器智能提醒
//迭代器遍历
Iterator<Integer> integerIterator = set.iterator();
while (integerIterator.hasNext()) {
System.out.println(integerIterator.next());//1 4 7 重复是数据没存进来
}
//增强型for循环遍历,底层是迭代器
for (int i : set){
System.out.println(i);//1 4 7 重复是数据没存进来
}
3、哈希值
哈希值是一个十进制的整数,由系统随机给出(就是对象的地址值,是第一个逻辑地址,是模拟出来的地址值,不是数据实际存储的的物理地址值)
获取哈希值的方法 int hashCode();
4、HashSet存储的数据结构
JDK1.8之前:哈希表 = 数组 + 链表;
JDK1.8之后:哈希表 = 数组 + 红黑树(提高查询速度);
哈希表的特点:查询速度快;
5、set集合存储元素不重复原理
基本思路:
当set调用add方法的时候,会将当前所要存储的元素的哈希值在集合中查找,若未查找到,则存储集合,若查找到则会调用equals方法,与集合中已经存在的相同哈希值的元素进行比较,若返回true则不再将所要存储的元素存储到集合中,若返回false则将所要存储的元素存储到集合中。
6、HashSet存储自定义类型元素
1、概述
要想将自定义的类存入到HashSet必须重写hashCode和equals方法(以保障元素唯一);
2、使用
要求:同名和同年龄的人视为一个人,不允许存储两个;
person类:
public class Person {
private String name;
private int age;
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Persion{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Person persion = (Person) o;
return age == persion.age &&
Objects.equals(name, persion.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
Test测试类:
public class MyHashSet {
public static void main(String[] args) {
Set<Person> set = new HashSet<>();
set.add(new Person("小明",18));
set.add(new Person("小兰",19));
set.add(new Person("小明",18));
System.out.println(set);
//[Person{name='小兰', age=19}, Person{name='小明', age=18}]
}
}
7、LinkedHashSet(了解)
简介:
具有可预知迭代顺序的 Set 接口的哈希表和链接列表实现;
此实现与 HashSet 的不同之外在于,后者维护着一个运行于所有条目的双重链接列表;
底层是哈希表+链表;
HashSet:无序的,不允许重复;
LinkedHashSet:有序的,不允许重复;
8、可变参数
使用场景:
当参数的数据类型已经确定,但参数的个数不确定,此时可使用可变参数;
使用格式:
修饰符 返回值类型 方法名(数据类型...变量名){}
可变参数原理:
可变参数底层是一个数组,根据传入的参数数量不同,创建不同长度的数组,来存储这些参数;
传递的参数数量可以为0;
public class Test {
public static void main(String[] args) {
System.out.println(sum(1,2,3,4,5,6,7,8,9,0,7,56,4,4,6,67,64));//253
}
public static int sum(int...arr){
//实际上arr可以当做一个数组用
int sum = 0;
for(int i:arr){
sum+=i;
}
return sum;
}
}
注意事项:
只能有一个可变参数;
如果有多个参数,可变参数必须写在参数列表末尾;