目录
Java - Set接口:
* java.util.Set接口 extends Collection接口
* Set接口的特点:
* 1.不允许存储重复的元素
* 2.没有索引,没有带索引的方法,也不能使用普通的for循环遍历
HashSet集合:
* java.util.HashSet集合 implements Set接口
* HashSet特点:
* 1.不允许存储重复的元素
* 2.没有索引,没有带索引的方法,也不能使用普通的for循环遍历
* 3.是一个无序的集合,存储元素和取出元素的顺序有可能不一致
* 4.底层是一个哈希表结构(查询速度非常快)
import java.util.*;
public class Main {
public static void main(String[] args) {
Set<Integer> set = new HashSet<>();
//使用add 方法往集合中添加元素
set.add(1);
set.add(3);
set.add(2);
set.add(1);
System.out.println(set);
//使用迭代器遍历set集合
Iterator<Integer> it = set.iterator();
while(it.hasNext()){
Integer x = it.next();
System.out.println(x);
}
System.out.println("-------------");
//使用增强for遍历set集合
for(Integer i : set){
System.out.println(i);
}
}
}
//HashSet 集合内,元素唯一有序排列
P.S.Set 集合不允许出现重复元素的原理
* 哈希值:是一个十进制的整数,由系统随机给出(就是对象的地址值,是一个逻辑地址
* 是模拟出来得到地址,不是数据实际存储的物理地址),在Object类有一个方法
* 可以获取对象的哈希值。
* int hashCode()
* 返回该对象的哈希码值
* Set 集合不允许出现重复元素的原理
* Set集合在调用add方法的时候,add方法会调用元素的hashCode方法和equals方法,判断元素是否重复
* 如果没有哈希冲突,则把元素加入集合,如果由哈希冲突,调用equals方法,若返回true
* 认定两个元素相同,就不会把元素加入集合;若返回false则认定两个元素不同,把元素加入集合。
HashSet存储自定义类型元素
import java.util.*;
/*
* HashSet存储自定义类型元素
* set集合报错元素唯一:
* 存储的元素(String, Integer,...Student, Person...)必须重写hashCode方法和equals方法
* 要求:
* 同名同年龄的人,视为同一个人,只能存储一次
*/
public class Main {
public static void main(String[] args) {
//创建HashSet集合存储Person
HashSet<Person> set = new HashSet<>();
Person p1 = new Person("迪丽热巴", 18);
Person p2 = new Person("迪丽热巴", 18);
Person p3 = new Person("迪丽热巴", 19);
set.add(p1);
set.add(p2);
set.add(p3);
System.out.println(set);
//[Person{name='迪丽热巴', age=19}, Person{name='迪丽热巴', age=18}, Person{name='迪丽热巴', age=18}]
System.out.println(p1.hashCode());//460141958
System.out.println(p2.hashCode());//1163157884
System.out.println(p1 == p2); // false
System.out.println(p1.equals(p2));//false
}
}
//以下为定义的 Person 类,注意必须重写hashCode方法和equals方法
import java.util.Objects;
public class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public Person(){
}
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;
Person person = (Person) o;
return age == person.age &&
Objects.equals(name, person.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
LinkedHashSet集合
链表实现的HashSet,集合内 的顺序与输入顺序相同
import java.util.*;
/*
* java.util.LinkedHashSet集合 extends HashSet集合
* LinkedHashSet集合特点:
* 底层是一个哈希表(数组+链表/红黑树)+链表:多了一条链表(记录元素的存储顺序),保证元素有序
*
*/
public class Main {
public static void main(String[] args) {
HashSet<String> set = new HashSet<>();
set.add("www");
set.add("abc");
set.add("abc");
set.add("itcast");
System.out.println(set);//[abc, www, itcast]无序,不允许重复
LinkedHashSet<String> linked = new LinkedHashSet<>();
linked.add("www");
linked.add("abc");
linked.add("abc");
linked.add("itcast");
System.out.println(linked);//[www, abc, itcast]有序,不允许重复
}
}