Set集合
HashSet
特点
- HashSet的元素是不可重复的,存储无序,底层数组结构是哈希表,判断两个元素是否重复根据元素类重写的hashCode()和equals()方法;
Set<String> set = new HashSet<String>();
set.add("猪八戒");
set.add("猪大");
set.add("猪二");
set.add("猪三");
set.add("猪二");
for (String s : set) {
System.out.println(s);
}
输出结果为:猪三 猪大 猪八戒 猪二
HashSet底层本质是HashMap,内部无序,封装了HashMap。就是用HashMap的key位来存储值。
//set集合内部的封装的HashMap对象
private transient HashMap<E,Object> map;
public HashSet() {
map = new HashMap<>();
}
/**
*HashSet底层初始容量为16
*/
public HashSet(Collection<? extends E> c) {
map = new HashMap<>(Math.max((int) (c.size()/.75f) + 1, 16));
addAll(c);
}
如果添加的元素相==或equals HashSet就只会保留其中一个。当我们将自己写的类存入set集合时一定要重写 equals和hashCode
public class User {
private Integer id;
private String name;
private String hobby;
public User() {
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public User(Integer id, String name, String hobby) {
this.id = id;
this.name = name;
this.hobby = hobby;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
", hobby='" + hobby + '\'' +
'}';
}
}
没有重写equals和HashCode方法之前
public static void main(String[] args) {
Set<User> set = new HashSet<>();
set.add(new User(1,"猪八","睡觉"));
set.add(new User(2,"猪二","吃饭"));
set.add(new User(2,"猪二","吃饭"));
set.add(new User(1,"猪八","睡觉"));
Iterator<User> it = set.iterator();
while (it.hasNext()) {
System.out.println(it.next());
}
}
输出结果为 :
User{id=1, name='猪八', hobby='睡觉'}
User{id=2, name='猪二', hobby='吃饭'}
User{id=1, name='猪八', hobby='睡觉'}
User{id=2, name='猪二', hobby='吃饭'}
重写后
public static void main(String[] args) {
Set<User> set = new HashSet<>();
set.add(new User(1,"猪八","睡觉"));
set.add(new User(2,"猪二","吃饭"));
set.add(new User(2,"猪二","吃饭"));
set.add(new User(1,"猪八","睡觉"));
Iterator<User> it = set.iterator();
while (it.hasNext()) {
System.out.println(it.next());
}
}
输出结果为 :
User{id=1, name='猪八', hobby='睡觉'}
User{id=2, name='猪二', hobby='吃饭'}
二、TreeSet
特点
- TreeSet基于TreeMap实现,TreeSet其实于是基于红黑树的。
- TreeSet有个特点,插入无序内部有序。
插入数据实现Comparable接口,通过compareTo方法去比较大小,或者在实例化TreeSet的时候自定义排序Comparator方法。内部的int compare(T o1, T o2)比较对象大小。
如果插入数据即不实现Commparable或在插入的时候也不指定排序方式Comparator那么就会报错。
public static void main(String[] args) {
Set<String> set = new TreeSet<>();
set.add("3");
set.add("1");
set.add("2");
set.add("4");
for (String str : set) {
System.out.println(str);
}
}
输出结果为: 1 2 3 4
重写Commparable可以切换比较方式
public static void main(String[] args) {
Set<User> set = new TreeSet<>();
set.add(new User(1,"猪",1));
set.add(new User(2,"八",12));
set.add(new User(3,"戒",1222));
Iterator<User> iterator = set.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
}
输出结果为:
User{id=1, name='猪', age=12}
User{id=2, name='八', age=23}
User{id=3, name='戒', age=34}