Set集合
概述:
set集合特点:无序 无下标 不可重复
方法全部继承自collection
set集合中区别对象是不是唯一的标准是:两个对象的hashcode是否一样,再判定两个对象是否equals
set接口的使用
添加数据 add
删除数据 remove
遍历:1.增强for
2.迭代器
判断 contains
非空 isempty
Set<String> set = new HashSet();
set.add("华为");
set.add("苹果");
set.add("小米");
System.out.println(set.size());
System.out.println(set.toString());
//set.remove("华为");
//System.out.println(set.size());
//遍历 1.增强for
for (String x:set
) {
System.out.println(x);
}
System.out.println("___________");
//2.迭代器
Iterator<String> iterator = set.iterator();
while (iterator.hasNext()){
System.out.println(iterator.next());
}
System.out.println(set.contains("华为"));
System.out.println(set.isEmpty());
set实现类
hashset
HashSet<String> hashSet = new HashSet();
基于hashcode实现 元素不重复
当存入元素的哈希码相同时,会调用equals进行确认,如结果为true,则拒绝后者存入
hashset的存储过程
根据hashcode计算保存的位置。
如果此位置为空,则直接保存。
如果不为空,执行equals方法,如果equals方法为true,则认为是重复。否则:形成链表。
判断重复的依据:hashcode和equals
set集合中区别对象是不是唯一的标准是:两个对象的hashcode是否一样,再判定两个对象是否equals
重写hashcode方法和equals方法
//hashcode方法重写
public int hashCode() {
int n1 = this.name.hashCode();
int n2 = this.age;
return n1+n2;
}
重写hashcode方法中,会加一个数字。一般是质数 17或者31
原因:1. 31是一个质数,减少散列冲突
- 提高执行效率 31*i=(i<<5)-i i的5次方 左移五位
treeset
普通元素
TreeSet<String> treeSet = new TreeSet();
treeSet.add("abc");
treeSet.add("bcd");
红黑树,节点颜色不同
二叉查找树,一个节点最多有两个子节点
基于排列顺序实现元素不重复
实现了SortedSet接口,对集合元素自动排序
元素对象的类型必须实现Comparable接口,指定排序规则
通过Compareto方法确定是否为重复元素
复杂元素
报错 classcastexception
在二叉树中,左边的元素比右边的小,但是程序不知道如何比较大小,所以报错。
要求:元素必须要实现comparable接口,接口里要实现抽象方法 public int compareTo。(此方法视为比较规则)
方法返回0,则认为是重复元素。
compareTo方法
public class Person implements Comparable<Person>
public int compareTo(Person o) {
//n1==0时 说明姓名一样
int n1 = this.getName().compareTo(o.getName());
int n2 = this.age-o.getAge();
//n1=0时 说明名字相同,返回n2
//.n1不相同时,说明名字不同,直接返回n1
return n1==0?n2:n1;
}
比较规则:先按姓名比,再按年龄比
?
compareTo的作用是比较重复,与list中的重写equals,hashset中重写hashcode,equals的作用相同
?
Comparator接口(比较器)
Comparator接口:定制比较
Comparable接口:内置compareTo方法,适用于元素的类可以实现接口(比如自建的类),String类则使用Comparator比较器
匿名内部类
//创建集合并指定比较规则
TreeSet<Person>treeSet = 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;
}
});
案例
要求:使用TreeSet集合,实现字符串按长度排序,短到长
import java.util.Comparator;
import java.util.TreeSet;
public class Test {
public static void main(String[] args) {
//接口不能实例化,此处使用匿名内部类来实现接口
//创建集合并指定比较规则
TreeSet<String>treeSet = new TreeSet<>(new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
int n1 = o1.length()-o2.length();
int n2 = o1.compareTo(o2);
return n1==0?n2:n1;
}
});
treeSet.add("helloworld");
treeSet.add("zhang");
treeSet.add("lisi");
treeSet.add("wangwu");
treeSet.add("beijing");
treeSet.add("xian");
treeSet.add("nanjing");
System.out.println(treeSet.size());
System.out.println(treeSet.toString());
}
}