文章目录
- 一. HashSet
- 二. TreeSet
Set :无序无重复
- 具体的实现类
HashSet
TreeSet - 基本的使用
- 无序 ,无重复
无序:我们使用集合存放元素的顺序, 集合内取出来的顺序不一致
集合本身是有自己的算法排布顺序,hash算法
一. HashSet
常用方法 底层:(HashMap (数组+链表) 称为:散列表或者临接连表)
- java.util
- 如何创建对象:无参数; 有参数(规定数组的长度)
- 集合容器的基本使用:
增删改查:
- add(value);addAll(collection c);没有带索引的方法,因为Set本身是无顺序的。
- retainAll ; removeAll;
- remove(Object),没有带索引的删除方法没有,也是因为set本身是无序的。
- 没有set修改方法,因为元素没有顺序。
// 无序:我们使用集合存放元素的顺序, 集合内取出来的顺序不一致
HashSet<String> set = new HashSet<String>();
set.add("b");
set.add("a");
set.add("B");
set.add("c");
set.add("A");
set.add("C");
System.out.println(set);
//结果:[a,A,b,B,c,C]
//发现存储顺序 和 集合输出的顺序不一样。它内部有自己的存储顺序,按照自己的算法顺序。
set.remove("B");//只有删除元素这一种方法,没有删除索引号的方法了
System.out.println(set);
//结果:[a,A,b,c,C]
- 可以通过增强for循环遍历获得所有元素
for(String v:set){
System.out.println(v);
}
- 也可以使用迭代器获得所有元素,iterator()
//获取一个迭代器对象 通过set集合获取
Iterator<String> it = set.iterator();//Iterator接口 多态的效果
//判断下一个位置是否有元素
while(it.hasNext()){
String value = it.next();
System.out.println(value);
}
- size()获得元素的有效个数
- 无重复的原则
例子:
Person类:
public class Person {
private String name;
public Person(String name){
this.name=name;
}
public String getName(){
return this.name
}
}
主方法类:
public class TestHashSet {
public static void main(String[] args){
HashSet<Person> personSet = new HashSet<Person>();
personSet.add(new Person("郑中拓1"));
personSet.add(new Person("郑中拓2"));
personSet.add(new Person("郑中拓3"));
personSet.add(new Person("郑中拓4"));
personSet.add(new Person("郑中拓5"));
System.out.println("person集合的size:"+personSet.size());//5
HashSet<Person> personSet1 = new HashSet<Person>();
personSe1t.add(new Person("郑中拓"));
personSet1.add(new Person("郑中拓"));
personSet1.add(new Person("郑中拓"));
personSet1.add(new Person("郑中拓"));
personSet1.add(new Person("郑中拓"));
System.out.println("person集合的size:"+personSet1.size());//5
HashSet<String> stringSet = new HashSet<String>();
stringSet.add(new String("郑中拓"));
stringSet.add(new String("郑中拓"));
stringSet.add(new String("郑中拓"));
stringSet.add(new String("郑中拓"));
stringSet.add(new String("郑中拓"));
System.out.println("string集合的size:"+stringSet.size());//1
}
}
首先通过String类型和Person类型存储大概猜测:无重复的原则, 利用equals方法进行比较。
如果我们想要让Person对象的name一致,认为是同一个对象,我们可以重写equals方法进行试验。
public class Person {
private String name;
public Person(String name){
this.name=name;
}
public String getName(){
return this.name
}
//重写equals方法 将person放入set集合中 去掉重复
public boolean equals(Object obj) {
if(this==obj){
return true;
}
if(obj instanceof Person){
//obj还原回Person类型
Person anotherPerson = (Person)obj;
//this anotherPerson比较对象中的name属性
if(this.name.equals(anotherPerson.name)){
return true;
}
}
return false;
}
}
在运行主方法类,发现输出还是1和5,说明不单单是equals的问题。
重写了equals方法 发现还没有产生无重复的效果,证明可能原则不止equals一个方法这么简单,还有另一个规则同时起着作用 hashCode方法。
在Person类中在重写hashCode方法:
//重写 hashCode方法
public int hashCode(){
//两个person对象name属性一致 需要让hashCode返回值一致
return this.name.hashCode();
}
此时再去运行主方法,发现结果都是1了。所以set的无重复equals方法和hashCode方法同时作用的。
五个Person对象只剩一个,那么是第一次存储的,还是最后一次存储??
set集合是发现重复的元素, 拒绝存入,存储的是第一个。
二. TreeSet
TreeMap 二叉树,利用Node(left item right)
- 无序无重复 java.util
- 无参数构造方法 带Collection构造方法
- 基本常用方法
add(E e) ;iterator() ; remove(E e) ;没有修改 ;size(); - 无重复的规则是如何实现的
treeSet集合本身有顺序 , 我们指的无序存入的和取出来的不一致。
和compareTo方法类似---->String类 按照字母的自然顺序排布(Unicode)。
public class TestTreeSet {
public static void main(String[] args){
TreeSet<String> stringSet = new TreeSet<String>();
stringSet.add(new String("郑中拓"));
stringSet.add(new String("郑中拓"));
stringSet.add(new String("郑中拓"));
stringSet.add(new String("郑中拓"));
stringSet.add(new String("郑中拓"));
System.out.println(stringSet.size());//1 set家族如有相同的对象 拒绝存入
TreeSet<Person> personSet = new TreeSet<Person>();
personSet.add(new Person("郑中拓",18,1));
personSet.add(new Person("郑中拓",16,2));
personSet.add(new Person("郑中拓",20,3));
personSet.add(new Person("郑中拓",24,4));
personSet.add(new Person("郑中拓",25,5));
System.out.println(personSet.size());//???? 异常
//ClassCastException--->造型异常
}
}
如果想要把自己写的类型,比如Person对象存入TreeSet集合里,
不能随意的存储, 需要让自己写的类先实现Comparable接口。
public class Person implements Comparable<Person>{
//如果想要让person对象存入TreeSet集合内 必须实现接口 重写这个方法
public int compareTo(Person o) {
int value = this.name.compareTo(o.name);
if(value!=0){
return value;//当前对象name和另一个对象name的compateTo结果
}
return this.age-o.age;//返回值整数 靠后 返回值负数 靠前
}
}