1.Set集合介绍
Set继承于Collection接口,是一个不允许出现重复元素,并且无序的集合,主要有HashSet和TreeSet两大实现类。
1.1:特点
1.1.1:无序:Set集合数据添加的顺序和取出的顺序不一致
Set<Integer> set=new HashSet<Integer>();
set.add(2);
set.add(1);
set.add(5);
set.add(8);
System.out.println(set);
1.1.2:唯一:List集合数据允许添加重复数据
Set<Integer> set=new HashSet<Integer>();
set.add(2);
set.add(1);
set.add(5);
set.add(8);
set.add(8);
System.out.println(set);
1.1.3:问题:存储对象,验证Set集合唯一性
Set<User> set=new HashSet<User>();
set.add(new User(1,"zs"));
set.add(new User(2,"ls"));
set.add(new User(1,"zs"));
for (User user : set) {
System.out.println(user);
}
查看结果:存储相同属性的User对象时,Set集合并未满足唯一性要求,打印输入了相同对象信息。 输出格式:类的全路径名+@+十六进制内存地址
User user = new User();
user.equals(null); //跳转到equals方法查看源码
问题原因:判断重复元素的时候,Set集合会调用hashCode()和equal()方法来实现;而在没有重写equals方法之前默认比较的是Object(引用类型),实际上比较的是内存地址。
重写User对象中的equals方法,比较User对象中的属性。
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((id == null) ? 0 : id.hashCode());
result = prime * result + ((name == null) ? 0 : name.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;
User other = (User) obj;
if (id == null) {
if (other.id != null)
return false;
} else if (!id.equals(other.id))
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
当比较对象的属性相同时,已存在的对象信息不会被覆盖,而是过滤了。 结论:先比较hashcode值是否相同,再比较equals;
1.2:Set集合遍历方式
注意:在Set集合中数据是无序没有下标的,故不能使用for循环的方式
1.2.1:foreach
Set<String> set=new HashSet<String>();
set.add("zs");
set.add("ls");
set.add("ww");
for (String value : set) {
System.out.println(value);
}
1.2.2:迭代器(itreator)
Set<String> set=new HashSet<String>();
set.add("zs");
set.add("ls");
set.add("ww");
Iterator<String> it = set.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
1.3:常见的实现类
1.3.1:HashSet
-
它不允许出现重复元素;
-
不保证集合中元素的顺序
-
允许包含值为null的元素,但最多只能有一个null元素。
-
HashSet的实现是不同步的。
1.3.2:LinkedHashSet
-
哈希表和链表实现Set接口,具有可预测的迭代次序;
-
由链表保证元素有序,也就是说元素的存储和取出顺序是一致的。
-
由哈希值保证元素唯一,也就是说没有重复的元素
1.3.3:TreeSet
TreeSet 是一个有序的集合,它的作用是提供有序的Set集合。TreeSet是基于TreeMap实现的。TreeSet中的元素支持2种排序方式:自然排序 或者 根据创建TreeSet 时提供的 Comparator 进行排序。
java.lang.Comparable自然比较接口
public class User implements Comparable<User> {
private int id;
private String name;
...
@Override
public int compareTo(Student b) {
return this.id-b.id;
}
}
java.util.Comparator比较器
public class NameComparator implements Comparator<User> {
@Override
public int compare(User a, User b) {
return a.getName()-b.getName();
}
}