Set集合
package SetDemo;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
public class SetDemo {
public static void main(String[] args) {
/*
Set集合的特点:
1.Set系列集合的特点:
Set集合是一个存储元素不能重复的集合方式,因为存储数据的时候通过判断其元素的hashCode值,不一样再存储。
2.Set集合的实现类特点:
HashSet: 无序,不重复,无索引
LinkedHashSet:有序,不重复,无索引
TreeSet:可排序,不重复,无索引
3.Set集合的方法与Collection一致
需求:
利用Set系列的集合,添加字符串,并使用多种方式遍历。
迭代器
增强for
Lambda表达式
*/
// 1.创建set集合的对象
Set<String> set = new HashSet<>();
// 2.为set对象添加元素
boolean b1 = set.add("a");
boolean b2 = set.add("a");
set.add("c");
set.add("b");
set.add("e");
set.add("d");
System.out.println(b1);// true
System.out.println(b2);// false
// 3.循环输出集合中的元素
Iterator<String> iter = set.iterator();
// 迭代器
while (iter.hasNext()) {
System.out.println(iter.next());
}
// 增强for
for (String s : set) {
System.out.println(s);
}
// lambda表达式
set.forEach(System.out::println);
}
}
HashSet
package SetDemo;
import java.util.HashSet;
public class HashSetDemo {
public static void main(String[] args) {
/*
HashSet用于给数据去重,不需要保证数据的添加顺序时用(无序,不重复,无索引)
Hash值:
1.是根据hashCode方法算出来的int类型的整数
2.该方法定义在Object类中,所有对象都可以调用,默认使用地址值进行计算
3.一般情况下,重写hashCode方法,利用对象内部的属性值计算哈希值
对象的哈希值特点:
1. 如果没有重写hashCode方法,不同对象计算出的哈希值是不同的
2. 如果已经重写hashCode方法,不同的对象只要属性值相同,计算出的哈希值就是一样的
3. 在小部分情况下,不同的属性值或者不同的地址值计算出来的哈希值也有可能一样。(哈希碰撞)
4. String 和 Integer不需要重写hashCode方法,Java已经重写了,自定义对象要重写hashCode
需求:创建一个存储学生对象的集合,存储多个学生对象。
使用程序实现在控制台遍历该集合。
要求:学生对象的成员变量值相同,我们就认为是同一个对象
*/
//创建学生对象
Student stu1 = new Student("张三",18);
Student stu2 = new Student("张三",18);
Student stu3 = new Student("李四",18);
Student stu4 = new Student("王五",19);
// 创建HashSet集合
HashSet<Student> set = new HashSet<>();
// 1. 如果没有重写hashCode方法,不同对象计算出的哈希值是不同的
System.out.println(stu1.hashCode());//189568618
System.out.println(stu2.hashCode());//793589513
// 将学生对象存入集合( 要重写hashCode,否则就会有重复属性值的元素,因为添加元素是按照hash值来判断的 )
set.add(stu1);
set.add(stu2);
set.add(stu3);
set.add(stu4);
// 输出集合
System.out.println(set);//[name王五, age=19, name张三, age=18, name李四, age=18]
// 3.在小部分情况下,不同的属性值或者不同的地址值计算出来的哈希值也有可能一样。
//哈希碰撞
System.out.println("abc".hashCode());//96354
System.out.println("acD".hashCode());//96354
}
}
LinkedHashSet
package SetDemo;
import java.util.LinkedHashSet;
public class LinkedHashSetDemo {
public static void main(String[] args) {
/*
LinkedHashSet :用于给数据去重且要保证数据的添加顺序时用。(有序,不重复,无索引)
有序:指的是输出的顺序和添加元素时的顺序一致
*/
//1.创建4个学生对象
Student s1 = new Student("zhangsan",23);
Student s2 = new Student("lisi",24);
Student s3 = new Student("wangwu",25);
Student s4 = new Student("zhangsan",23);
//2.创建集合的对象
LinkedHashSet<Student> lhs = new LinkedHashSet<>();
//3.添加元素
System.out.println(lhs.add(s3));
System.out.println(lhs.add(s2));
System.out.println(lhs.add(s1));
System.out.println(lhs.add(s4));
//4.打印集合
System.out.println(lhs);//[namewangwu, age=25, namelisi, age=24, namezhangsan, age=23]
}
}
TreeSet
package SetDemo;
import java.util.TreeSet;
public class TreeSetDemo{
public static void main(String[] args) {
/*
TreeSet:用于数据唯一且需要按指定的要求排序时使用 (不重复,无索引,可排序)
可排序:按照元素的默认规则(由小到大)排序,字符类型按照ASCII码表的数字升序排列的
TreeSet基于红黑树的数据结构实现排序,增删改查性能都比较好
*/
/*
需求:
1.存储整数并进行排序
2.使用自定义类型,按元素的规则排序
排序方法:
给Student类实现Comparable接口,重写里面的抽象方法
*/
TreeSet<Integer> ts = new TreeSet();
// 1.存储整数并进行排序
ts.add(3);
ts.add(2);
ts.add(7);
ts.add(6);
ts.forEach(System.out::println);// 2 3 6 7
// 2.使用自定义类型,按元素的规则排序
TreeSet<Student> tss = new TreeSet();
Student stu1 = new Student("二",13);
Student stu2 = new Student("一",11);
Student stu3 = new Student("五",12);
Student stu4 = new Student("三",10);
tss.add(stu1);
tss.add(stu2);
tss.add(stu3);
tss.add(stu4);
System.out.println(tss);//[name三, age=10, name一, age=11, name五, age=12, name二, age=13]
}
}
Student类
package SetDemo;
import java.util.Objects;
public class Student implements Comparable<Student> {
private String name;
private int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public Student() {}
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 "name" + name + ", age=" + age;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student that = (Student) o;
return age == that.age && Objects.equals(name, that.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
@Override
// TreeSet排序规则
public int compareTo(Student o) {
// 指定排序的规则
// 按年龄进行排序;
// this表示当前要添加的元素,o表示已经存在于红黑树中的元素
System.out.println("this:"+this);
System.out.println("o:"+o);
return this.getAge()-o.getAge();
}
}