持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第13天,点击查看活动详情
Set是Java中的集合类,提供了一种无顺序,不重复的集合。常用的子类包括HashSet, TreeSet等。
HashSet底层使用HashMap实现,根据元素的hashCode和equals来判断是否为重复元素。当元素的hashCode相同且equals返回true时则认为是重复元素。因为使用了hash算法所以HashSet有很好的添加和访问性能。可以放入null但只能放一个null
TreeSet底层使用红黑树实现,Set上的元素被放在一个自动排序的红黑树中。不能放入null
HashSet
它不保证 set 的迭代顺序;特别是它不保证该顺序恒久不变。
package com.chen;
import java.util.HashSet;
import java.util.Set;
private static void hashSet() {
Set<String> set = new HashSet();
set.add("周泰");
set.add("关羽");
set.add("戏志才");
set.add("张角");
set.add("袁术");
set.add("曹操");
String[] names = set.toArray(new String[]{});
for(String s:names) {
System.out.println(s);
}
Cat c1 = new Cat("喵喵",5,"公");
Cat c2 = new Cat("咪咪",3,"母");
Cat c3 = new Cat("奶茶",4,"母");
Cat c4 = new Cat("喵喵",5,"公");
Set<Cat> cats = new HashSet<>();
cats.add(c1);
cats.add(c2);
cats.add(c3);
cats.add(c4);
cats.add(c2);
System.out.println(cats.size());
for(Cat c:cats) {
System.out.println(c);
}
System.out.println("c1="+c1.hashCode());
System.out.println("c2="+c2.hashCode());
System.out.println("c3="+c3.hashCode());
System.out.println("c4="+c4.hashCode());
}
public static void main(String[] args) {
}
}
package com.chen;
public class Cat {
private String name;
private int age;
private String 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 String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
@Override
public String toString() {
return "Cat [name=" + name + ", age=" + age + ", sex=" + sex + "]";
}
public Cat(String name, int age, String sex) {
super();
this.name = name;
this.age = age;
this.sex = sex;
}
public Cat() {
super();
}
@Override
public int hashCode() {
final int prime = 31;//系数
int result = 1;
result = prime * result + age;
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + ((sex == null) ? 0 : sex.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Cat other = (Cat) obj;
if (age != other.age)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
if (sex == null) {
if (other.sex != null)
return false;
} else if (!sex.equals(other.sex))
return false;
return true;
}
}
LinkedHashSet
HashSet的子类,它具有可预知迭代顺序的 Set 接口的哈希表和链接列表实现。此实现与 HashSet 的不同之外在于,后者维护着一个运行于所有条目的双重链接列表。此链接列表定义了迭代顺序,即按照将元素插入到 set 中的顺序(插入顺序)进行迭代。注意,插入顺序不 受在 set 中重新插入的 元素的影响。
private static void linkHashSet() {
LinkedHashSet<Cat> set = new LinkedHashSet<>();
Cat c1 = new Cat("喵喵",5,"公");
Cat c2 = new Cat("咪咪",3,"母");
Cat c3 = new Cat("奶茶",4,"母");
Cat c4 = new Cat("喵喵",5,"母");
set.add(c1);
set.add(c2);
set.add(c3);
set.add(c4);
for(Cat c:set) {
System.out.println(c);
}
}
TreeSet
使用元素的自然顺序对元素进行排序,引用数据类型使用比较器(Comparator)
排序:数字 ==> 英文(忽略大小写) ==> 中文
不可以添加的null元素,不然会java.lang.NullPointerException
private static void treeSet() {
TreeSet<Cat> tree = new TreeSet<>(new CatComparator());
Cat c1 = new Cat("喵喵",5,"公");
Cat c2 = new Cat("咪咪",3,"母");
Cat c3 = new Cat("奶茶",4,"母");
Cat c4 = new Cat("喵喵",5,"母");
tree.add(c1);
tree.add(c2);
tree.add(c3);
tree.add(c4);
System.out.println(tree.size());
for(Cat c:tree) {
System.out.println(c);
}
}