黑马程序员----JAVA----集合小结(Set)
来源:互联网 发布:ftp网络错误10053 编辑:程序博客网 时间:2024/06/13 23:44
----------------------------------android培训、java培训、期待与您交流!------------------------------
Set与Collection的关系
Set是一种Collection,即Set接口是Collection接口的子接口。
Set:元素是无序的(存入和取出的顺序不一致),元素是不可以重复的。
HashSet:底层数据结构使用的是哈希表。线程不同步;
HashSet是如何保证元素的唯一性的呢?
是通过元素的两个方法:hashcode和equals来完成的。
先比较hashcode(),在使用equals()比较。
如果hashCode()相等,再使用equals()比较;如果hashCode()不相等,那么就不再使用equals()比较了。
如果两个对象的equals()比较为true,那么hashCode()必须相同。
例如:Person比较的是两个对象的name、age、sex,
那么hashCode()使用name、age、sex的hashCode()相加,这就能保存上面的条件了。基本类型就本身也就可以了,要么也可以转换成对应的包装器类型,再去获取hashCode()。
添加元素的流程:
当把元素添加到哈希表中时,需要先找到元素对应的桶位,然后判断这个桶中是否存在这个元素,如果元素在桶中已经存在,那么添加失败;否则添加成功!
获取元素的哈希码值(使用元素的hashCode()方法);
通过哈希码值计算桶位(可以把哈希码值理解为就是桶位);
遍历桶中元素,使用元素的equals()方法,验证元素是否在桶中已经存在;
存在则添加失败,否则把元素添加到桶中。
添加元素的问题:
HashSet<Person> set = new HashSet<Person>();
Person p1 = new Person(“zhangSan”, 23, “male”);
Person p2 = new Person(“zhangSan”, 23, “male”);
set.add(p1);
set.add(p2);
上面代码中set.add(p2)的结果会添加成功!也就是说HashSet会认识p1和p2是两个不同对象。如果想让上面代码中set.add(p2)添加失败,我们需要让HashSet认为p1和p2是相等的。
set.add(p2):调用p2的hashCode()方法获取哈希码,通过哈希码找到桶。如果p1与p2的hashCode()不同,那么p2找到的桶就与p1找到的桶不同。
循环遍历p2对应桶中所有元素,使用equals()比较,如果没有相同元素,那么添加p2到这个桶中。
结论:就算p1.equals(p2)结果为true,但p1.hashCode() != p2.hashCode(),那么也是枉然!
LinkedHashSet是HashSet的子类
LinkedHashSet是HashSet的子类,也就是说LinkedHashSet底层也使用的是哈希表!
LinkedHashSet的迭代顺序是添加顺序!因为内部使用了链表来记录元素的添加顺序,迭代时再使用添加时顺序迭代!
TreeSet:
TreeSet是有序的,它会把元素排序,但如果元素没有自然顺序,那就出错。
要求元素类型,必须去实现Comparable接口。这个接口只有一个方法:
compareTo(T o),用来比较当前对象与参数对象谁大谁小。this > o,返回一个正数;this < 0,返回一个负数;否则返回0。
TreeSet用compareTo()方法保证元素的唯一性,如果新添加的元素,与当前Set中的元素使用compareTo比较结果为0,那么就说明元素已经存在,再添加就重复了,所以添加失败!
TreeSet特性:
不同步,即线程不安全 有序,无重复元素(所有的Set都有这个特性);
底层使用的是二叉树结构
TreeSet是怎么保证元素唯一性的?
要求元素具有可比性!
例如:数值类型都具有可比性:10 > 3
例如:String类型具有可比性:”abc”.compareTo(“def”) < 0
但是,Person没有可比性。
任何实现了Comparable接口的类都是具有可比性的!
当两个元素使用compareTo()方法比较返回0时,表示两个元素是相同的!
/*
演示CompareTo方法
*/
//创建一个类
public class ComparableDemo {
public static void main(String[] args) {
//创建集合对象
TreeSet<Person> ts=new TreeSet<Person>();
Person p1=new Person("changsan","male",32);
Person p2=new Person("bisi","male",22);
Person p3=new Person("aangwu","female",12);
//添加元素
ts.add(p1);
ts.add(p2);
ts.add(p3);
//遍历集合中的元素
for(Person p:ts){
System.out.println(p);
}
}
}
//实现Comparable接口
public class Person implements Comparable<Person> {
private String name;
private String sex;
private int age;
public Person(String name, String sex, int age) {
super();
this.name = name;
this.sex = sex;
this.age = age;
}
public Person() {
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;
Person other = (Person) 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;
}
@Override
public String toString() {
return "Person [name=" + name + ", sex=" + sex + ", age=" + age + "]";
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public int compareTo(Person p) {
int n = name.compareTo(p.name);
if(n != 0) {
return n;
}
n = age - p.age;
if(n != 0) {
return n;
}
return sex.compareTo(p.sex);
}}
上面代码先是比较两个对象的name,如果name可以分出大小,那么就返回结果;
如果name分不出大小,那么再去比较年龄,如果年龄分出大小,那么就返回结果;
如果年龄再分出不结果,那么最终以性别来比较。
//定义一个类实现Comparator接口,做个比较器
public class ComparatorDemo {
public static void main(String[] args) {
//创建一个内部类的接口比较器
TreeSet<Person> ts=new TreeSet<Person>(new Comparator<Person>(){
@Override
//重写compare 方法
public int compare(Person p1, Person p2) {
//获取p1对象的性别
/**/String str1=p1.getSex();
//获取p2对象的性别
String str2=p2.getSex();
//让他们进行比较如果对象1等于男,如果对象2等于女 就返回1,将当前对象返回。
//否则对象1等于女,如果对象2等于男,就返回-1,将当前对象返回。
if(str1.equals("male")){
if(str2.equals("female")){
return 1;
}
}else{
if(str2.equals("male"));
return -1;
}
//比较年龄
/**/int i=p1.getAge()-p2.getAge();
i f(i!=0){
return i;
}
//比较姓名
return p1.getName().compareTo(p2.getName());
}
});
//将Perosn对象添加到集合中
ts.add(new Person("changsan","male",32));
ts.add(new Person("bisi","female",22));
ts.add(new Person("aangwu","male",22));
//创建接口的迭代器
Iterator<Person> it=ts.iterator();
//遍历集合中的元素
while(it.hasNext()){
System.out.println(it.next());
}
}
}
----------------------------------android培训、java培训、期待与您交流!------------------------------
- 黑马程序员----JAVA----集合小结(Set)
- 黑马程序员--java集合Set
- 黑马程序员 java基础之set集合
- 黑马程序员---Java基础---Set集合
- 黑马程序员-Java集合框架Set
- 黑马程序员--集合Set总结--java
- 黑马程序员---java基础之集合Set
- 黑马程序员-java基础-set集合
- 黑马程序员-------Set集合
- 黑马程序员-------Set集合
- 黑马程序员--Set集合
- 黑马程序员----JAVA----集合小结(List)----
- 黑马程序员-Java集合框架小结
- 《黑马程序员》java Map集合知识小结
- 黑马程序员--Java集合的小结
- 黑马程序员--集合小结
- 黑马程序员---集合小结
- 奋斗黑马程序员----Java集合框架之Set集合
- 国内银行应用软件项目外包模式探讨
- vi命令大全
- Struts2原来是那么的简单!
- [Java]读取文件方法大全
- 黑马程序员-银行业务调度系统
- 黑马程序员----JAVA----集合小结(Set)
- StringTokenizer类的使用
- 开源 免费 java CMS - FreeCMS-功能说明-信息管理 .
- 远程桌面关机三种方法
- C#Winform去掉边框后,窗体最大化,任务栏被遮挡问题!
- 开源 免费 java CMS - FreeCMS-功能说明-信息管理 .
- JNI实例3---扫描SD卡中mp3文件,native层调用Java自定义的类
- 学习LinearLayout布局
- Linux安装和卸载JDK(Java)