1.HashSet
存储结构:哈希表 JDK1.7(数组+链表) JDK1.8(数组+链表+红黑树)
存储过程:根据hashcode计算保存位置,若为空则直接保存,不为空执行equals方法,若equals方法返回true则认为重复,否则形成链表
1.基于HashCode实现元素不重复
2.当存入元素的哈希码相同时,会调用equals进行确认,若结果为true,则拒绝后者存入
import java.util.HashSet;
import java.util.Iterator;
/**
* HashSet集合
* 哈希表 JDK1.7(数组+链表) JDK1.8(数组+链表+红黑树)
*/
public class Demo02 {
public static void main(String[] args) {
//新建集合
HashSet<String> hashSet = new HashSet<String>();
//添加
hashSet.add("包子");
hashSet.add("馒头");
hashSet.add("窝窝头");
hashSet.add("辣条");
hashSet.add("泡芙");
System.out.println("元素个数:" + hashSet.size());
System.out.println(hashSet.toString());
//删除
hashSet.remove("泡芙");
System.out.println("元素个数:" + hashSet.size());
//遍历
System.out.println("-----增强for-----");
for (String string: hashSet) {
System.out.println(string);
}
System.out.println("-----迭代器-----");
Iterator<String> it = hashSet.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
//判断
System.out.println(hashSet.contains("窝窝头"));
System.out.println(hashSet.isEmpty());
}
}
创建Person类
public class Person {
private String name;
private int age;
public Person(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 String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
测试类
import java.util.HashSet;
public class Demo03 {
public static void main(String[] args) {
//创建集合
HashSet<Person> persons = new HashSet<>();
//添加
Person s1 = new Person("Jack",10);
Person s2 = new Person("Tom",20);
Person s3 = new Person("Linda",30);
persons.add(s1);
persons.add(s2);
persons.add(s3);
//persons.add(s3);
persons.add(new Person("Jack",10)); //添加新对象
System.out.println("元素个数:" + persons.size());
System.out.println(persons.toString());
}
}
重复元素可以被添加,虽然添加的对象的内容和原对象相同,但地址与原对象不同,故可以被添加
重写Person类中的hashCode方法,若被添加的对象名字的哈希值和年龄之和与原对象相等,不为空所以执行equals方法,比较的是两对象的地址,返回false,故新添加对象存在于链表中,重复元素依然可以被添加
@Override
public int hashCode() {
int n1 = this.name.hashCode();
int n2 = this.age;
return n1 + n2;
}
重写equals方法
IDEA生成
@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 boolean equals(Object obj) {
if(this == obj){ //被添加对象与原对象地址相同,认为重复,返回true,不添加
return true;
}
if(obj == null){ //被添加对象为空,返回false,不重复,形成链表
return false;
}
if(obj instanceof Person){ //判断被添加对象与该类的类型是否相同
Person p = (Person)obj;
if(this.name.equals(p.getName()) && this.age == p.getAge()){ //若被添加对象的名字与年龄相同,返回true,认为重复,不添加
return true;
}
}
return false;
}
被添加对象的内容与原对象相同,通过重写equals方法,认为它们是重复的,所以不能添加
添加、删除、遍历、判断
public class Demo03 {
public static void main(String[] args) {
//创建集合
HashSet<Person> persons = new HashSet<>();
//添加
Person s1 = new Person("Jack",10);
Person s2 = new Person("Tom",20);
Person s3 = new Person("Linda",30);
persons.add(s1);
persons.add(s2);
persons.add(s3);
//persons.add(s3);
persons.add(new Person("Jack",10));
System.out.println("元素个数:" + persons.size());
System.out.println(persons.toString());
//删除
//persons.remove(s1);
// persons.remove(new Person("Jack",10)); //先通过hashcode比较地址,再通过equals比较内容
// System.out.println("元素个数:" + persons.size());
//遍历
System.out.println("----增强for----");
for (Person person: persons) {
System.out.println(person.toString());
}
System.out.println("----迭代器----");
Iterator<Person> it = persons.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
//判断
System.out.println(persons.contains(s2));
//System.out.println(persons.contains(new Person("Jack",10)));
System.out.println(persons.isEmpty());
}
}
2.TreeSet
存储结构:红黑树
1.基于排列顺序实现元素不重复
2.实现了SortedSet接口,对集合元素自动排序
3.元素对象的类型必须实现Comparable接口,指定排序规则
4.通过CompareTo方法确定是否为重复元素
新建Person类,并且实现Comparable接口,重写compareTo方法,返回值为0则认为是重复元素
import java.util.Objects;
public class Person implements Comparable<Person>{
private String name;
private int age;
public Person(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 String toString() {
return "Person{" +
"name='" + name + '\'' +
", 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 int compareTo(Person o) {
int n1 = this.getName().compareTo(o.getName()); //比较名字
int n2 = this.age - o.getAge(); //比较年龄
return n1==0?n2:n1; //返回值为0则重复
}
}
import com.yl.collection.Set.Person;
import java.util.Iterator;
import java.util.TreeSet;
/**
* TreeSet
* 存储结构:红黑树
* 元素必须实现Comparable接口,compareTo方法返回值为0则认为是重复元素
*/
public class Demo02 {
public static void main(String[] args) {
//创建集合
TreeSet<Person> persons = new TreeSet<>();
Person s1 = new Person("Jack",10);
Person s2 = new Person("Tom",20);
Person s3 = new Person("Linda",30);
Person s4 = new Person("Linda",20);
//添加
persons.add(s1);
persons.add(s2);
persons.add(s3);
persons.add(s4);
System.out.println("元素个数:" + persons.size());
System.out.println(persons.toString());
//删除
persons.remove(s1);
//persons.remove(new Person("Linda",20));
System.out.println("元素个数:" + persons.size());
//遍历
System.out.println("----增强for---");
for (Person person: persons) {
System.out.println(person);
}
System.out.println("----迭代器----");
Iterator<Person> it = persons.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
//判断
System.out.println(persons.contains(s1));
System.out.println(persons.contains(new Person("Linda",30)));
System.out.println(persons.isEmpty());
}
}
Comparator接口,能够实现定制比较(比较器)
import com.yl.collection.Set.Person;
import java.util.Comparator;
import java.util.TreeSet;
/**
* Comparator:实现定制比较(比较器)
* Comparable:可比较
*/
public class Demo03 {
public static void main(String[] args) {
//创建集合并指定比较规则
TreeSet<Person> persons = new TreeSet<>(new Comparator<Person>() {
//先比较年龄,后比较姓名
@Override
public int compare(Person o1, Person o2) {
int n1 = o1.getAge() - o2.getAge();
int n2 = o1.getName().compareTo(o2.getName());
return n1==0?n2:n1;
}
});
Person s1 = new Person("Jack",10);
Person s2 = new Person("Tom",20);
Person s3 = new Person("Linda",30);
Person s4 = new Person("Ami",20);
//添加
persons.add(s1);
persons.add(s2);
persons.add(s3);
persons.add(s4);
System.out.println(persons.toString());
}
}
案例:使用TreeSet集合实现字符串按长度进行排序
import java.util.Comparator;
import java.util.TreeSet;
//使用TreeSet集合实现字符串按长度进行排序
public class Demo04 {
public static void main(String[] args) {
//创建集合
TreeSet<String> treeSet = new TreeSet<>(new Comparator<String>() {
//指定比较规则
@Override
public int compare(String o1, String o2) {
int n1 = o1.length() - o2.length();
int n2 = o1.compareTo(o2);
return n1==0?n2:n1;
}
});
//添加
treeSet.add("shaokao");
treeSet.add("huoguo");
treeSet.add("xiaomila");
treeSet.add("nuojiya");
treeSet.add("wangzaixiaomantou");
treeSet.add("xiaohuangren");
System.out.println(treeSet.toString());
}
}