Set继承自Collection
Set特点:
- 不包含重复元素集合
- 没有带索引的方法,所以不能使用普通for循环遍历
- HashSet:对集合迭代顺序不做任何保证
示例:
package Set;
import java.util.HashSet;
import java.util.Set;
public class SetDemo01 {
public static void main(String[] args) {
Set<String> set=new HashSet<String>();
set.add("hello");
set.add("world");
set.add("java");
set.add("world");
//增强for遍历
for(String s:set) {
System.out.println(s);
}
System.out.println(set);
}
}
哈希表:
- JDK8之前,底层采用数组加链表实现
- JDK8之后,在长度较长的时候,底层实现了优化
- HashSet默认构造方法:创建一个新的空集合,默认初始容量为16
哈希表存储时,首先计算出一个哈希值作为索引,对于索引相同的元素,先看哈希值是否相同,不同则存入,相同就看元素内容是否相同,不相同则存入,相同表示已存在,不再存入。
哈希值: 是JDK根据对象的地址或者字符串或者数字算出来的int类型的数值
- Object类中public int hasCode():返回对象的哈希值
哈希值特点:
- 同一个对象多次调用hasCode()方法返回的哈希值相同
- 默认情况下,不同对象哈希值不同,通过方法重写,可以实现不同对象的哈希值相同
- 字符串重写了hashCode方法
示例:
学生类:
package Set;
public class student {
private String name;
private int age;
//构造方法
public student() {
System.out.println("无参构造");
}
public student(String name,int age) {
this.name=name;
this.age=age;
}
//提供get/set方法
public void setAge(int age) {
if(age<0||age>100)
{
System.out.println("年龄有误");
}else {
this.age=age;
}
}
public int getAge() {
return age;
}
public void setName(String name) {
this.name=name;
}
public String getName() {
return name;
}
public void show() {
System.out.println(name+","+age);
}
}
main:
package Set;
import java.util.HashSet;
import java.util.Set;
public class SetDemo02 {
public static void main(String[] args) {
student s1=new student("小李",20);
student s2=new student("小李",20);
student s3=new student("小张",40);
//同一个对象多次调用hasCode()方法返回的哈希值相同
System.out.println(s1.hashCode());
System.out.println(s1.hashCode());
//默认情况下,不同对象哈希值不同
//通过方法重写,可以实现不同对象的哈希值相同
System.out.println(s2.hashCode());
System.out.println("-------");
System.out.println("hello".hashCode());
System.out.println("world".hashCode());
System.out.println("hello".hashCode());
System.out.println("-------");
//字符串重写了hashCode方法
System.out.println("你好".hashCode());
System.out.println("晚安".hashCode());
}
}
HashSet特点:
- HashSet实现了Set接口
- 底层数据结构是哈希表
- 对集合迭代顺序不做任何保证,不保证存储和取出的元素顺序一致
- 没有带索引的方法,所以不能使用普通for循环遍历
- 不包含重复元素
示例:
package Set;
import java.util.HashSet;
public class HashSetDemo {
public static void main(String[] args) {
HashSet<String> hs=new HashSet<>();
hs.add("hello");
hs.add("world");
hs.add("java");
for(String s:hs) {
System.out.println(s);
}
}
}
LinkedHashSet特点:
- 哈希表和链表实现的Set接口,具有可预测的迭代次序
- 由链表保证有序,元素的存储和取出顺序一致
- 由哈希表保证元素唯一,没有重复的元素