点击上方蓝色文字,加关注,获取更多推文
哈喽大家好,小哥来了,昨天小哥累了休息了一下,就没有推文了,那今天补上哈,老套路,看标题!
来吧:谈谈自己适不适合干软开。
这是母校的图书馆哦
Set:包括HashSet和TreeSet,HashSet又包括linkedHashSet,同时Set也是派生于Collection,也是一个单列集合
特点:无序且不可存放重复的元素,连null都必须存一份,底层是Map集合
HashSet:无序,线程不安全,效率高(底层用的是HashMap,在1.8之前是基于哈希表的,在1.8之后值基于哈希表+红黑树),默认大小是16,加载因子是0.75,每次扩容1倍。
TreeSet:可用于排序,底层是TreeMap(基于红黑树)
LinkedHashSet:有序,这个的有序是链表的特性导致的,底层是基于哈希表+红黑树+双向链表
Set set = new HashSet();
set.add("1");
set.add("d");
set.add("a");
set.add("125");
set.add("125");
set.add(null);
set.add(null);
System.out.println(set);
运行结果:[null, 1, a, d, 125]
无序,会将重复的元素保留一个,不存在索引,因为是链式的
设计一个list,将里面重复的元素去掉(从list到set可以去掉重复的元素,从set到list可以取到元素的索引,实用性非常高):代码如下
Set set = new HashSet();
List list = new ArrayList();
list.add("hhhhh");
list.add("hhhhh");
list.add("hhhhh");
list.add("hhhhh");
list.add("458");
list.add("cccc");
list.add("cccc");
set.addAll(list);
System.out.println("去掉重估之前"+list);
System.out.println("去掉重复之后"+set);
运行结果:
去掉重估之前[hhhhh, hhhhh, hhhhh, hhhhh, 458, cccc, cccc]
去掉重复之后[hhhhh, 458, cccc]
判断list中元素是否相同:
public class Entrance {
public static void main(String[] args) {
List list=new ArrayList();
list.add(new PersonTwo("李四",20));
boolean b=list.contains(new PersonTwo("李四", 20));
System.out.println(b);
}
}
class PersonTwo{
String nameString;
int age;
public PersonTwo(String nameString, int age) {
this.nameString = nameString;
this.age = age;
}
@Override
public String toString() {
return "Person [nameString=" + nameString + ", age=" + age + "]";
}
}
运行结果:false
为什么是false尼:因为此时只对比的是地址值,以上代码明显就是两个不同的地址。怎样可以让false变为true 请看下方代码,解析看注释
public class Entrance {
public static void main(String[] args) {
List list=new ArrayList();
list.add(new PersonTwo("李四",20));
boolean b=list.contains(new PersonTwo("李四", 20));
System.out.println(b);
}
}
class PersonTwo{
String nameString;
int age;
public PersonTwo(String nameString, int age) {
this.nameString = nameString;
this.age = age;
}
@Override
public String toString() {
return "Person [nameString=" + nameString + ", age=" + age + "]";
}
@Override
public boolean equals(Object obj) {
if(this==obj) {
return true;
}
if(obj instanceof PersonTwo) {
PersonTwo personTwo = (PersonTwo)obj;
if(this.age==personTwo.age && this.nameString.equals(personTwo.nameString)) {
return true;
}else {
return false;
}
}else {
return false;
}
}
}
运行结果:true
原因就是我自定义的类中没有覆写Object中的equals方法,因此,当我覆写这个方法后,我规定,当所有属性都相等时则表示为true
下一个话题:Set集合可以去重的原因:
是因为hashCode和equals方法
首先判断两个对象的hashCode值(一个十六进制的地址值,是根据对象的地址以及属性算出来的,也叫散列值)是否相等,如果相等,判断equals是否为true,都满足,才会认为时一个对象,否则不是一个对象
二话不说,上例子
public class Entrance {
public static void main(String[] args) {
Set set = new HashSet();
set.add(new PersonTwo("王五", 20));
set.add(new PersonTwo("王五", 20));
System.out.println(set.toString());
}
}
class PersonTwo {
String nameString;
int age;
public PersonTwo(String nameString, int age) {
this.nameString = nameString;
this.age = age;
}
@Override
public String toString() {
return "Person [nameString=" + nameString + ", age=" + age + "]";
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj instanceof PersonTwo) {
PersonTwo personTwo = (PersonTwo) obj;
if (this.age == personTwo.age && this.nameString.equals(personTwo.nameString)) {
return true;
} else {
return false;
}
} else {
return false;
}
}
}
运行结果:[Person [nameString=王五, age=20], Person [nameString=王五, age=20]]
此时是set但是没有去重,为什么尼:
看下面代码
public class Entrance {
public static void main(String[] args) {
Set set = new HashSet();
set.add(new PersonTwo("王五", 20));
set.add(new PersonTwo("王五", 20));
System.out.println(set.toString());
}
}
class PersonTwo {
String nameString;
int age;
public PersonTwo(String nameString, int age) {
this.nameString = nameString;
this.age = age;
}
@Override
public String toString() {
return "Person [nameString=" + nameString + ", age=" + age + "]";
}
@Override
public int hashCode() {
//这个地方一般是认为设定的,我还可直接return this.nameString
return this.nameString.hashCode()+this.age;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj instanceof PersonTwo) {
PersonTwo personTwo = (PersonTwo) obj;
if (this.age == personTwo.age && this.nameString.equals(personTwo.nameString)) {
return true;
} else {
return false;
}
} else {
return false;
}
}
}
运行结果:[Person [nameString=王五, age=20]]
因为我覆写了Object中的hashCode了
为什么在基本数据类型中,set可以去掉重复-------------------------------------------------------------------------------------------------这个问题,大家去思考吧,思考完了可以公众号恢复小哥,有惊喜哦。
下一个话题:TreeSet:可以自动帮助我们排序,底层基于hashMap--基于红黑树,直接上例子:
Set treeSet=new TreeSet();
treeSet.add(1);
treeSet.add(6);
treeSet.add(2);
treeSet.add(8);
treeSet.add(9);
System.out.println(treeSet);
运行结果:
[1, 2, 6, 8, 9]
说到这里,小哥要普及一下数据结构的知识:
在二叉排序树中:他的遍历方式有三种
前序:也就是根左右,先根后左再右
中序:也就是左根右,先左后根再右
后续:也就是左右根,先左后右再根
那TreeSet默认的是中序遍历,下面小哥来画一个图:就拿代码中的例子,如下:
其他的大家自己研究了:
这里有道题:
先序:2 3 6 4 7 9 8
中序:6 3 2 9 7 4 8
后续:?
写出后续发送公众号有惊喜哦----------------------------------------------
下一个话题:
方式一:TreeSet通过实现Comparable接口覆写compareTo进行排序:
public class Entrance {
public static void main(String[] args) {
Set treeSet=new TreeSet();
treeSet.add(new PersonTwo("张胜男", 20));
treeSet.add(new PersonTwo("李嘉诚", 25));
treeSet.add(new PersonTwo("高斯", 29));
treeSet.add(new PersonTwo("四哦分",30));
treeSet.add(new PersonTwo("张是", 50));
System.out.println(treeSet);
}
}
class PersonTwo implements Comparable{
String nameString;
int age;
public PersonTwo(String nameString, int age) {
this.nameString = nameString;
this.age = age;
}
@Override
public int compareTo(Object o) {
if(o instanceof PersonTwo) {
PersonTwo personTwo = (PersonTwo)o;
if(this.age>personTwo.age) {
return 1;
}else if(this.age==personTwo.age) {
return 0;
}else {
return -1;
}
}else {
return -1;
}
}
@Override
public String toString() {
return "PersonTwo [nameString=" + nameString + ", age=" + age + "]";
}
}
运行结果:
[PersonTwo [nameString=张胜男, age=20], PersonTwo [nameString=李嘉诚, age=25], PersonTwo [nameString=高斯, age=29], PersonTwo [nameString=四哦分, age=30], PersonTwo [nameString=张是, age=50]]
方式二:通过实现Comparator接口覆写compare方法进行比较排序
这样的好处是有效的分离对象和比较规则。代码如下:
public class Entrance {
public static void main(String[] args) {
Set treeSet=new TreeSet(new MyComparator());
treeSet.add(new PersonTwo("张胜男", 20));
treeSet.add(new PersonTwo("李嘉诚", 25));
treeSet.add(new PersonTwo("李嘉诚", 25));
treeSet.add(new PersonTwo("高斯", 29));
treeSet.add(new PersonTwo("四哦分",30));
treeSet.add(new PersonTwo("张是", 50));
System.out.println(treeSet);
}
}
class MyComparator implements Comparator{
@Override
public int compare(Object o1, Object o2) {
if(o1 instanceof PersonTwo && o2 instanceof PersonTwo) {
PersonTwo personTwo = (PersonTwo)o1;
PersonTwo personTwo2 = (PersonTwo)o2;
if(personTwo.age>personTwo2.age) {
return 1;
}else if(personTwo.age==personTwo2.age) {
if(personTwo.nameString.compareTo(personTwo2.nameString)>0) {
return 1;
}else if(personTwo.nameString.compareTo(personTwo2.nameString)==0) {
return 0;
}else {
return -1;
}
}else {
return -1;
}
}else {
return -1;
}
}
}
class PersonTwo{
String nameString;
int age;
public PersonTwo(String nameString, int age) {
this.nameString = nameString;
this.age = age;
}
@Override
public String toString() {
return "PersonTwo [nameString=" + nameString + ", age=" + age + "]";
}
}
运行结果:
[PersonTwo [nameString=张胜男, age=20], PersonTwo [nameString=李嘉诚, age=25], PersonTwo [nameString=高斯, age=29], PersonTwo [nameString=四哦分, age=30], PersonTwo [nameString=张是, age=50]]
总结一下:
comparable:使对象的属性在本类中实现比较并排序
comparator:使对象和这种排序规则分离。
终于总结结束了,一首西安人的歌送给大家,听着歌声,大家晚安,晚安,晚安
动起你的小手,右下方点赞点在看,让我们一起站在风口浪尖,听西安人的歌