文章目录
回顾:上一章了解了 List集合的一些案例( listj集合框架 ) 本章来了解一下 set集合
1)set集合的特点
1、无重复(无重复指:基本数据类型&String类型);2、无序
源代码:
package com.hemingxiang.set;
import java.util.HashSet;
import java.util.Iterator;
/**
* set集合的特点:不重复 无序
* 不重复指基本数据类型&String
* @author Administrator
*
*/
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());
System.out.println("------增强for循环(无序)-------");
for (Object obj : set) {
System.out.println(obj);
}
System.out.println("--------迭代器(无序)------");
Iterator<Object> it = set.iterator();
while(it.hasNext()) {
System.out.println(it.next());
}
}
}
①不重复
源代码不重复效果图:
②无序
源代码无序效果图:
2)set去重复的底层原理
先看源代码:
package com.hemingxiang.set;
import java.util.HashSet;
/**
* set去重复的底层原理
* @author Administrator
*/
public class Demo2 {
public static void main(String[] args) {
HashSet<Object> set = new HashSet<>();
set.add(new Person("张三",18));
set.add(new Person("李四",20));
set.add(new Person("麻子",23));
set.add(new Person("李四",20));
set.add(new Person("老六",19));
System.out.println(set.size());
}
}
class Person implements Comparable<Person>{
private String name;
private int age;
private int level;
public Person(int level) {
super();
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 int getLevel() {
return level;
}
public void setLevel(int level) {
this.level = level;
}
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
public Person(String name, int age, int level) {
super();
this.name = name;
this.age = age;
this.level = level;
}
public Person() {
super();
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + ", level=" + level + "]";
}
@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;
}
//用于Demo3!!!!!!!
@Override
public int compareTo(Person o) {
int levelRes=this.level-o.level;
return levelRes == 0 ? this.age - o.age : levelRes;
}
}
运行出来的效果如下图:
这是没有进行去重的,如需去重复 同样需要重写equals方法;与list集合去重复不同的是set集合需重写hashCode方法
原理1:
第一个加进去时候不需要比较,当第二加进去的时候,就跟第一个比较一次,再第三个加进去的时候比较两次,以此类推,当第五个加进去的时候就比较四次了。
equals的判断要留下。
原理2:
当hasCode为1的时候,equals也为true的时候,就判定为了一个元素。
底层的基础原理就两个:
先调用hashCode的值,相等,在去比equals,如果hashCode都不相等,就不会去调用equals方法了。
🤔两条结论
结论:
①set去重底层原理是与对象的hashCode和equals方法有关 ②判断重复元素的时候,是先比较hashCode值,如果相等在调用equals比较内容,不相等就不调equals
3)set集合排序
源代码:
package com.hemingxiang.set;
import java.util.Comparator;
import java.util.TreeSet;
/**
* set集合排序
* java.lang.Comparable:自然排序接口,但排序的规则是单一的,不能应对复杂变化的需求
* java.util.Comparable:比较器排序
* @author Administrator
*
*/
public class Demo3 {
public static void main(String[] args) {
/**
* 需求1:假设从XX公司,拿到用户数据,根据用户的级别进行会议的座位排序
* 张三:部门总监1
* 李四:员工2
* 王五:部门经理3
* 麻子:组长4
* .....
*
* 需求2:按照年龄进行升序,并打印出人员信息
* int levelRes=this.level-o.level;
return levelRes==0?this.age - o.age : levelRes;
*
* 需求3:按照用户名字的首字母进行排序
*
*/
//如果要令它可以进行排序,在Demo2中的实体类实现Comparable接口即可
//TreeSet set=new TreeSet<>(new levelcomparator());//实现一个比较器接口,这样做的优点可以针对于同样一组数据做不同处理
//TreeSet<Person> set=new TreeSet<>((x,y)->x.getName().compareTo(y.getName()));
TreeSet<Person> set=new TreeSet<>((x,y)->{
int ageRes=x.getAge() - y.getAge();
int levelRes=0;
if(ageRes==0) {
levelRes=x.getLevel() - y.getLevel();
}
else {
return ageRes;
}
return levelRes;
});
set.add(new Person("ww",29,3));
set.add(new Person("zs",18,1));
set.add(new Person("mz",19,4));
set.add(new Person("ls",24,2));
set.add(new Person("bj",24,5));//增加一个人员
for (Object obj : set) {
System.out.println(obj);
}
}
}
class levelcomparator implements Comparator<Person>{
@Override
public int compare(Person o1, Person o2) {
int levelRes = o1.getLevel() - o2.getLevel();
return levelRes==0 ? o1.getAge() - o2.getAge() : levelRes;
}
}
看效果
😦自然排序接口 java.lang.Comparable
需求1
需求2
🙄比较器排序接口 java.util.Comparable
需求3
3个需求和起来的代码效果