目录
【思维导图】
一、Set的特点
①不可重复
解释:“李四”增加了两次,但输出结果时只有一个“李四”。
②无序
解释:增加时的顺序为:张三——李四——王二——麻子
输出时为:李四——张三——麻子——王二
代码块展示:
package com.chenchen.set;
import java.util.HashSet;
import java.util.Iterator;
/**
*
* Set集合的特点:
* ①不重复:基本数据类型 String = "abc";(如果是引入对象类型的话就是可以重复的 String= new String())
* ②无序
*
* @author ChenChen
*@date 2022年6月8日 下午4:41:02
*/
public class Demo1 {
public static void main(String[] args) {
HashSet<Object> set = new HashSet<>();
set.add("张三");
set.add("李四");
set.add("王二");
set.add("麻子");
set.add("李四");
System.out.println(set.size());//打印set集合长度
System.out.println("=======增强for=====");
for (Object object : set) {//循环遍历
System.out.println(object);
}
System.out.println("=======迭代器=====");
Iterator<Object> it = set.iterator();
while(it.hasNext()) {
System.out.println(it.next());
}
}
}
输出结果:
=======增强for=====
李四
张三
麻子
王二
=======迭代器=====
李四
张三
麻子
王二
注意:
之所以输出的结果不存在重复的情况,是因为存的是基本数据类型的值(eg:String ="张三";),如果存的值是引入对象类型的话就是可以重复的 (eg:String= new String();)。
可以重复情况下:代码展示:
package com.chenchen.set;
import java.util.HashSet;
import java.util.Iterator;
/**
* @author ChenChen
*@date 2022年6月8日 下午6:02:42
*/
public class Demo2 {
public static void main(String[] args) {
HashSet<Object> set = new HashSet<>();
//实例化一个对象
set.add(new Person("麻子",18));
set.add(new Person("张三",33));
set.add(new Person("李四",14));
set.add(new Person("王二",16));
set.add(new Person("麻子",18));
System.out.println(set.size());//打印set集合长度 集合容量为5
Iterator<Object> it = set.iterator();
while(it.hasNext()) {
System.out.println(it.next());//打印结果
}
}
}
}
输出结果:
二、Set集合的遍历方式
代码块展示:
package com.chenchen.set;
import java.util.HashSet;
import java.util.Iterator;
/**
*
* set底层去重复原理
* 1.set去重底层原理是与对象的hashcode以及equals方法有关
* 2.判断重复元素的时候,是先比较hashcode的值,在调用equals进行比较内容
*
* @author ChenChen
*@date 2022年6月8日 下午6:02:42
*/
public class Demo2 {
public static void main(String[] args) {
HashSet<Object> set = new HashSet<>();
set.add(new Person("麻子",18));
set.add(new Person("张三",33));
set.add(new Person("李四",14));
set.add(new Person("王二",16));
set.add(new Person("麻子",18));
System.out.println("set集合的长度:"+set.size());//打印set集合长度
System.out.println("=======迭代器=====");
Iterator<Object> it = set.iterator();
while(it.hasNext()) {
System.out.println(it.next());
}
}
}
//创建一个实体类
class Person /*implements Comparable<Person>*/{
private String name;
private int age;
private int level;
public Person(String name, int age, int level) {
super();
this.name = name;
this.age = age;
this.level = level;
}
public int getLevel() {
return level;
}
public void setLevel(int level) {
this.level = level;
}
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 Person() {
// TODO Auto-generated constructor stub
}
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + ", level=" + level + "]";
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + age;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return 1;//如果result定义为1时,那么就会调用
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Person other = (Person) obj;
if (age != other.age)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
}
输出结果:
Person [name=麻子, age=18, level=0]
Person [name=张三, age=33, level=0]
Person [name=李四, age=14, level=0]
Person [name=王二, age=16, level=0]
三、HashSet哈希表存储、重复元素存储底层探究
代码块展示:
package com.chenchen.set;
import java.util.HashSet;
import java.util.Iterator;
/**
*
* set底层去重复原理
* 1.set去重底层原理是与对象的hashcode以及equals方法有关
* 2.判断重复元素的时候,是先比较hashcode的值,在调用equals进行比较内容
*
* @author ChenChen
*@date 2022年6月8日 下午6:02:42
*/
public class Demo2 {
public static void main(String[] args) {
HashSet<Object> set = new HashSet<>();
set.add(new Person("麻子",18));
set.add(new Person("张三",33));
set.add(new Person("李四",14));
set.add(new Person("王二",16));
set.add(new Person("麻子",18));
System.out.println(set.size());//打印set集合长度
System.out.println("=======迭代器=====");
Iterator<Object> it = set.iterator();
while(it.hasNext()) {
System.out.println(it.next());
}
}
}
//创建一个实体类
class Person{
private String name;
private int 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;
}
public Person() {
// TODO Auto-generated constructor stub
}
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
@Override
public int hashCode() {
System.out.println("=====hashCode=======");
final int prime = 31;
int result = 1;
result = prime * result + age;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
System.out.println("=====equals=======");
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Person other = (Person) obj;
if (age != other.age)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
}
输出结果:
解释:
之所以调用了5次hashcode方法是因为存了5个值进去;调用了1次equals方法是因为将所有值进行比较,找出了含有1个重复的值,调用equals方法将其去除。所以最后的set集合的长度为4,输出的结果不存在重复的情况。
四、TreeSet(自然排序、比较排序)
①自然排序
代码块展示:
package com.chenchen.set;
import java.util.TreeSet;
/**
* Set集合排序
*
* @author ChenChen
*@date 2022年6月8日 下午8:20:26
*/
public class Demo3 {
public static void main(String[] args) {
TreeSet set = new TreeSet<>();
set.add("2");
set.add("9");
set.add("5");
set.add("6");
set.add("3");
set.add("8");
for (Object object : set) {
System.out.println(object);
}
}
}
输出结果:
错误演示:
package com.chenchen.set;
import java.util.TreeSet;
/**
* Set集合排序
*
* @author ChenChen
*@date 2022年6月8日 下午8:20:26
*/
public class Demo3 {
public static void main(String[] args) {
/**
* 提问环节:
* 从xxx公司,拿到用户数据,需要根据用户的级别,进行会议座位的排序
*eg:
* 张三 部门总监 1
* 李四 普通员工 3
* 麻子 部门经理 2
*
* 现象:
* 1.String默认是能够排序的
* 2.自定义的对象无法排序,报类型转换异常
*/
// Exception in thread "main" java.lang.ClassCastException:
// com.chenchen.set.Person cannot be cast to java.lang.Comparabley 意思是:Person类不能直接转换为Comparable接口
TreeSet set = new TreeSet<>();
set.add(new Person("张三",18,1));
set.add(new Person("王二",15,4));
set.add(new Person("麻子",20,2));
set.add(new Person("李四",20,3));
for (Object object : set) {
System.out.println(object);
}
}
}
解释:
String默认是能够排序的原因是因为String在底层代码里实现了Comparable接口,但是自定义的对象无法排序,报类型转换异常。
如果想让自定义对象实现排序就要将该对象的类实现Comparable接口。代码展示:
package com.chenchen.set;
import java.util.HashSet;
import java.util.Iterator;
/**
*
* @author ChenChen
*@date 2022年6月8日 下午6:02:42
*/
public class Demo2 {
//创建一个实体类
class Person implements Comparable<Person>{
private String name;
private int age;
private int level;
public Person(String name, int age, int level) {
super();
this.name = name;
this.age = age;
this.level = level;
}
public int getLevel() {
return level;
}
public void setLevel(int level) {
this.level = level;
}
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 Person() {
// TODO Auto-generated constructor stub
}
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
@Override
public int compareTo(Person o) {
// TODO Auto-generated method stub
return this.level - o.level;
}
}
注意:
输出结果:
Person [name=张三, age=18]
Person [name=麻子, age=20]
Person [name=李四, age=20]
Person [name=王二, age=15]
增加时的顺序:张三——王二——麻子——李四
输出时的顺序:张三——麻子——李四——王二
按照属性值level排序,排序成功!
②比较器排序
代码块展示:
ok,本章内容分享完毕,下期预告Map集合知识点,若本文章内容出现错误,还望指正。