Set接口
- 特点:无序,无下标,元素不可重复
- 方法:全部继承自Collection中的方法
Set实现类
HashSet
public static void main(String[] args) {
//创建集合
HashSet<String> set = new HashSet<>();
set.add("apple");
set.add("melon");
set.add("oriange");
set.add("apple");
System.out.println(set);//oriange,apple,melon
// set.remove("apple");
// System.out.println(set);
//遍历:增强for
for (String s : set) {
System.out.println(s);
}
//迭代器
Iterator<String> ite = set.iterator();
while(ite.hasNext()){
System.out.println(ite.next());
}
//判断
System.out.println(set.contains("apple"));
System.out.println(set.isEmpty());
}
- HashSet的使用:
- 根据hashcode计算保存的位置,如果此位置为空则直接保存,否则执行第2步
- 执行equals方法,如为true,则认为是重复,否则,形成链表
- 只重写hashcode(),属性相同的对象仍可以添加到HashSet中,因为执行了第2步
- 只重写equals(),Set 进行去重操作时,会先判断两个对象的 hashCode 是否相同,此时因为没有重写 hashCode 方法,所以会直接执行 Object 中的 hashCode 方法,而 Object 中的 hashCode 方法对比的是两个不同引用地址的对象,所以结果是 false,那么 equals 方法就不用执行了,直接返回的结果就是 false:两个对象不是相等的,于是就在 Set 集合中插入了两个相同的对象。
- 不同对象的 hashCode 可能相同;但 hashCode 不同的对象一定不相等
TreeSet
- 存储结构:红黑树,红黑树是一种平衡二叉查找树的变体
- 基于排列顺序实现元素不重复
- 实现了SortedSet接口,对集合元素自动排序
- 元素对象的类型必须实现Comparable接口,指定排序规则
- 通过CompareTo()方法确定是否为重复元素
public class Person implements Comparable<Person> {
//先按姓名比,再按年龄比
@Override
public int compareTo(Person o) {
int n1 = name.compareTo(o.getName());
int n2 = age-o.getAge();//返回负数,从小到大
//int n2 = o.getAge()-age;//返回正数,从大到小
return n1==0?n2:n1;
}
public static void main(String[] args) {
TreeSet<Person> strings = new TreeSet<>();
Person s1 = new Person("su", 16);
Person s2 = new Person("li", 33);
Person s3 = new Person("gu", 45);
strings.add(s1);
strings.add(s2);
strings.add(s3);
System.out.println(strings);
//[Person{name='gu', age=45}, Person{name='li', age=33}, Person{name='su', age=16}]
}
Comparator
- 实现定制比较(比较器)
- Comparator和Comparable区别:
- Comparable相当于“内部比较器”,而Comparator相当于“外部比较器”。
- 两种方法各有优劣, 用Comparable 简单, 只要实现Comparable 接口的对象直接就成为一个可以比较的对象,但是需要修改源代码。 用Comparator 的好处是不需要修改源代码, 而是另外实现一个比较器, 当某个自定义的对象需要作比较的时候,把比较器和对象一起传递过去就可以比大小了, 并且在Comparator 里面用户可以自己实现复杂的可以通用的逻辑,使其可以匹配一些比较简单的对象,那样就可以节省很多重复劳动了。
匿名内部类
public static void main(String[] args) {
//创建集合,并指定比较规则
TreeSet<Person> strings = new TreeSet<>(new Comparator<Person>() {
@Override
public int compare(Person o1, Person o2) {
int n1 = o1.getAge()-o2.getAge();
int n2 = o1.getName().compareTo(o2.getName());
return n1==0?n2:n1;
}
});
Person s1 = new Person("li", 45);
Person s2 = new Person("li", 33);
Person s3 = new Person("su", 16);
strings.add(s1);
strings.add(s2);
strings.add(s3);
System.out.println(strings);
//[Person{name='gu', age=45}, Person{name='li', age=33}, Person{name='su', age=16}]
}
public static void main(String[] args) {
Comparator<Person> comparator = new Comparator<Person>() {
@Override
public int compare(Person o1, Person o2) {
int n1 = o1.getAge()-o2.getAge();
int n2 = o1.getName().compareTo(o2.getName());
return n1==0?n2:n1;
}
@Override
public boolean equals(Object obj) {
return false;
}
};
TreeSet<Person> strings = new TreeSet<>(comparator);
Person s1 = new Person("li", 45);
Person s2 = new Person("li", 33);
Person s3 = new Person("su", 16);
strings.add(s1);
strings.add(s2);
strings.add(s3);
System.out.println(strings);