1.Set集合
Set集合也是Collection的子接口
也是用来储存数据的
特点:储存数据是无序且不可重复的
Set下面的的两个主要的实现类:
HashSet:
是靠Hash值进行储存的,特点是无序且不可重复,如果两个数据的Hash值一样就不会继续储存
TreeSet:
底层是二叉数,是按照Hash值进行从小到大的顺序给元素自然排序的,存储是无序的
2HashSet类
HashSet下面的方法和Collection 还有Set的方法是一样的
它也有自己的一些独有的方法
但是总体和ArrayList差不多
但是需要注意HashSet集合里储存的数据是无序的,没有规则的存入的
public class Demo1 {
public static void main(String[] args) {
Set <String> set = new HashSet<>();
set.add("a");
set.add("b");
set.add("c");
set.add("m");
set.add("ab");
set.add("bc");
set.add("ca");
set.add("abccd");
System.out.println(set);
//[a, ab, bc, b, c, abccd, m, ca]
}
}
2.1HashSet存储对象
package com.ccx.Set_;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
public class Test1 {
public static void main(String[] args) {
Aaa aaa1 = new Aaa("张三",18);
Aaa aaa2 = new Aaa("张三",18);
Aaa aaa5 = new Aaa("李四",40);
Aaa aaa3 = new Aaa("王五",35);
Aaa aaa4 = new Aaa("麻九",22);
Set <Aaa> set = new HashSet<>();
set.add(aaa1);
set.add(aaa2);
set.add(aaa3);
set.add(aaa4);
set.add(aaa5);
System.out.println(set);
//打印结果:[Aaa{名字是'王五', 年龄是35}, Aaa{名字是'李四', 年龄是40},
//Aaa{名字是'张三', 年龄是18}, Aaa{名字是'麻九', 年龄是22}]
//是无序的,且不能重复
}
}
class Aaa{
private String name;
private int age;
public Aaa(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 "Aaa{" +
"名字是'" + name + '\'' +
", 年龄是" + age +
'}';
}//可以更改其打印的内容修饰
@Override
public boolean equals(Object o) {//重写这个equals的原因是为了让再对比时候两个对象的内容一样也相等
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Aaa aaa = (Aaa) o;
return age == aaa.age && Objects.equals(name, aaa.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
}
总结:HashSet集合里的储存方式是按照哈希码值储存的,所以两个数据的哈希码值一样的情况下就会视为相同,在储存对象时它是把对象的地址转为哈希码进行对比存储,那么就会出现内容相同但是地址不同的重复数据,但是我们在使用时注重的是数据内容的相同,所以需要被存入的对象的类需要重写Object的equals方法和hashCode方法 。
3.TreeSet集合
TreeSet集合也是实现了Set集合,也是无序且不可重复的
package com.ccx.Set_;
//import java.util.HashSet;
//import java.util.Objects;
import java.util.Set;
import java.util.TreeSet;
public class Demo1 {
public static void main(String[] args) {
Set <String> set = new TreeSet<>();
set.add("a");
set.add("b");
set.add("c");
set.add("m");
set.add("ab");
set.add("bc");
set.add("ca");
set.add("abccd");
System.out.println(set);
//TreeSet在储存的时候是会自动排序,因为它实现了Comparator接口
//但是和储存的顺序毫无关系
}
}
class Person {
private String name;
private int age;
private char sex;
public Person(String name, int age, char sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
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;
}
public char getSex() {
return sex;
}
public void setSex(char sex) {
this.sex = sex;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
", sex=" + sex +
'}';
}
}
3.1TreeSet里存对象
package com.ccx.Set_;
import java.util.Objects;
import java.util.Set;
import java.util.TreeSet;
public class Demo1 {
public static void main(String[] args) {
Set <Person> treeSet = new TreeSet<>();
treeSet.add(new Person("张三",18,'男'));
treeSet.add(new Person("李四",20,'男'));
treeSet.add(new Person("王五",16,'男'));
System.out.println(treeSet);
//如果想要在TreeSet集合中存入对象,那么需要这个对象实现Comparable<>这个接口
//并且要去重写它的compareTo方法,而且需要返回一个int类型的数据
//他是按照这个int类型的数据进行排序,
// 如果返回的是个负整数那么就等于当前的数小于对比的数,会把这个数放在前面
//如果返回的是个正整数那么就等于当前的数大于对比的数,会把这个数放在前面
// 如果返回0就等于相等,就不会储存
//如果没有实现Comparable这个接口的话就会出现类转换异常
}
}
class Person implements Comparable<Person>{//这个泛型必须要填你要存入对比的类型
private String name;
private int age;
private char sex;
public Person(String name, int age, char sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
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;
}
public char getSex() {
return sex;
}
public void setSex(char sex) {
this.sex = sex;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
", sex=" + sex +
'}';
}
@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 && sex == person.sex && Objects.equals(name, person.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age, sex);
}
@Override
public int compareTo(Person o) {//重写Comparable的方法
return this.age - o.age;//返回一个int类型的值用来排序
}
}
TreeSet的储存会进行一个排序,这个排序是按照二叉树进行排序的,需要实现Comparable这个接口,并实现他的方法给返回一个int类型的值用来排序
总结:
1.HashSet存对象的时候,一定在类中重写equals和hashCode方法
2.TreeSet存对象的时候,一定要实现一个接口Comparable,重写compareTo方法 比较两个对象某个属性的int类型差值