Set
一、概述和特点
1.概述
Set在util包下,用法和Collection一样,自身没有特殊的用法。
2.特点
- 不包含重复元素
- 没有带索引的方法(不能用普通for循环遍历)
3.实例(字符串遍历)
package SetStudy;
import java.util.HashSet;
import java.util.Set;
public class Demo {
public static void main(String[] args) {
//创建集合对象
Set<String> s = new HashSet<String>();
//添加元素
s.add("hello");
s.add("world");
s.add("java");
s.add("world");
//遍历
for (String string : s) {
System.out.println(string);
}
}
}
二、Hash值
1.概述
Hash值是JDK根据对象的地址或者字符串或者数字算出来的int类型的数值。
Object类中有一个方法可以获取对象的Hash值(public int hashCode())。
2.对象哈希值的特点
- 同一个对象多次调用hashCode()得到的哈希值是一样的。
- 默认情况下,不同对象的哈希值不同。(通过重写hashCode方法可以实现不同对象的哈希值相同)
三、HashSet集合
1.概述
HashSet在util包下,该类实现了Set接口,由哈希表支持。
2.特点
- 底层数据结构是哈希表
- 不保证存储和取出元素的顺序一致
- 没有带索引的方法(不能用普通for循环遍历)
- 不包含重复元素(因为是Set集合)
3.实例(存储学生对象)
Demo类:
package SetStudy;
import java.util.HashSet;
public class Demo {
public static void main(String[] args) {
//创建集合对象
HashSet<Student> hs = new HashSet<>();
//创建学生对象
Student s1 = new Student("qwe",1);
Student s2 = new Student("asd",2);
Student s3 = new Student("zxc",3);
Student s4 = new Student("qwe",1);
//添加元素
hs.add(s1);
hs.add(s2);
hs.add(s3);
hs.add(s4);
//遍历
for (Student s : hs) {
System.out.println(s.getName() + ","+ s.getAge());
}
}
}
Student类(为保证唯一性要重写equals和hashCode方法):
package SetStudy;
public class Student {
private String name ;
private int age ;
public Student() {
}
public Student(String name, int age) {
this.name = name;
this.age = 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;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student student = (Student) o;
if (age != student.age) return false;
return name != null ? name.equals(student.name) : student.name == null;
}
@Override
public int hashCode() {
int result = name != null ? name.hashCode() : 0;
result = 31 * result + age;
return result;
}
}
4.哈希表概述
JDK8之前,底层采用数组加链表实现,可以说是一个元素为链表的数组;JDK8以后,在长度较长的时候,底层实现了优化。
四、LinkedHashSet集合概述和特点
1.概述
LinkedHashSet在util包下,是由哈希表和链表实现的Set接口,具有可预测的迭代次数。
2.特点
- 具有可预测的迭代次数
- 存储和取出元素的顺序是一致的(链表保证)
- 没有重复元素(哈希表保证)
3.实例(字符串遍历)
package SetStudy;
import java.util.HashSet;
import java.util.LinkedHashSet;
public class Demo {
public static void main(String[] args) {
//创建集合对象
LinkedHashSet<String> lhs = new LinkedHashSet<>();
//添加元素
lhs.add("hello");
lhs.add("world");
lhs.add("java");
lhs.add("hello");
//遍历
for(String s : lhs){
System.out.println(s);
}
}
}
五、TreeSet集合概述和特点
1.概述和特点
- 元素按照一定的规则进行排序,具体排序方法取决于构造方法,TreeSet()是根据元素的自然顺序进行排序(小->大),TreeSet(Comparator comparator)是根据指定的比较排序器排序。
- 没有带索引的方法(不能使用普通for循环遍历)
- 不包含重复元素(Set集合)
2.实例(存储整数集合并遍历)
注: 集合存储的是引用类型,所有基本类型的数据要用包装类。
package SetStudy;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.TreeSet;
public class Demo {
public static void main(String[] args) {
//创建集合对象
TreeSet<Integer> ts = new TreeSet<>();
//集合存储的是引用类型,所有基本类型的数据要用包装类。
//添加元素
ts.add(10);//自动装箱
ts.add(30);
ts.add(50);
ts.add(40);
ts.add(20);
ts.add(30);
//遍历
for(Integer i : ts){
System.out.println(i);
}
}
}