2.Set接口(HashSet,LinkedHashSet,TreeSet )
2.1.HashSet实现类:主要作用是去重
2.1.1.按照Hash算法来存储集合中的元素;
扩展:什么是Hash算法?
哈希算法又叫散列算法,是将任意长度的二进制值映射为较短的固定长度的二进制值,这个小的二进制值称为哈希值!
简单理解就是:将一段任意长度并且复杂的信息转化为一个固定长度简洁的字符串
举例理解:
有两个网址A,B(很长,很难记住),于是将A转化为数字1,B转化为数字2。
根据数字作为下标,就可以快速查到对应网址的信息,这个转化过程就是Hash算法!!!
2.1.2.不能保证元素的顺序,元素是无序的
(1)由于是无序的所以每组数据都没有索引,很多list可用的方法他都没有
(2)凡是需要通过索引来进行操作的方法都没有
(3)不能使用普通for循环来进行遍历,只有加强型for和迭代器两种遍历方法
2.1.3.不是同步的,需要外部保持线程之间的同步问题
扩展:同步,异步(这里简单提及)
同步方式、异步方式主要是由客户端(client)控制的
1.同步(sync):就是必须一件一件事做,等前一件做完了才能做下一件事;
2.异步(Async):相对同步而言的!当一个异步过程调用发出后,调用者在没有得到结果之前,就可以继续执行后续操作;
2.1.4集合元素值允许为null
2.1.5.底层是采用HashMap实现的(也是借助HashMap的方法来实现的,即封装了HashMap的方法)
注:HashSet应用代码示例如下
1.添加元素:
HashSet<String> set = new HashSet<String>();
set.add(“aaa”);
set.add("null");
2.删除元素:
HashSet<String> set = new HashSet<String>();
set.remove(“aaa”);//成功就返回true,失败返回false
3.对比查找
HashSet<String> set = new HashSet<String>();
set.contains(“aaa”);//集合中存在该元素就返回true,否则返回false
4.清空集合
HashSet<String> set = new HashSet<String>();
set.clear();//清空集合所有元素,返回null的[]
5.获取长度
HashSet<String> set = new HashSet<String>();
set.size();
当我们加入的对象是自定义对象是,必须要重写Object类中的hashCode和equals方法 !!
代码示例:这里自定义一个Student 类(有俩变量,一个是名字.一个是年龄)
public class Student {
//省略get()/set()
private String name;
private int age;
public Student(String name, int age) {
super();
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + "]";
}
//重写hashCode方法
@Override
public int hashCode() {//这里返回的是要添加的对象的哈希值}
//重写equals方法
@Override
public boolean equals(Object obj) {
Student student = (Student)obj;
if (student.name.equals(this.name)&&student.age == this.age){return true; }
return false; }
}
HashSet<Student> hashSet = new HashSet<>();
hashSet.add(new Student("小红", 15));
hashSet.add(new Student("小王", 17));
hashSet.add(new Student("小红", 15));
System.out.println(hashSet );//输出结果[Student [name=小红, age=15], Student [name=小王, age=17]]
如果不重写hashCode(),equals(),输出结果将会是:[Student [name=小红, age=15], Student [name=小王, age=17],Student [name=小红, age=15]]
2.2.LinkedHashSet实现类:
2.2.1.相对HashSet来说,LinkedHashSet存储结构是一个双向链表
2.2.2.存储的元素是有序的,但任然不可重复
2.2.3.LinkedHashSet继承自HashSet(唯一的区别是LinkedHashSet内部使用的是LinkHashMap)
2.2.4.LinkedHashSet需要维护元素的插入顺序,因此性能略低于HashSet的性能
2.3.TreeSet实现类:主要作用是排序(默认升序)
2.3.1.是一个有序的集合;
2.3.2.TreeSet采用二叉树的数据结构来存储集合元素;
2.3.3.TreeSet对加入元素默认按照升序进行排序;
2.3.4.需要注意的是放入TreeSet集合中的元素必须是可“排序”的;
2.3.5.对加入的元素(自定义类),若要实现compareTo方法,必须实现Comparable接口
注:TreeSet应用代码示例如下 :
TreeSet<Integer> treeSet = new TreeSet<>()
treeSet.add(2);
treeSet.add(1);
treeSet.add(6);
treeSet.add(5);
treeSet.add(2);
System.out.println(treeSet);//输出结果[1,2,5,6],会将对象排序并将重复的删除了
当我们加入的对象是自定义对象是,必须要实现compareTo接口并且重写compareTo接口方法 !!
代码示例:这里自定义一个Student 类(有俩变量,一个是名字.一个是年龄)
public class Student implements Comparator<Student>{
//省略get()/set()
private String name;
private int age;
public Student(String name, int age) {
super();
this.name = name;
this.age = age;
}
//重写comparable接口中的抽象方法,主要是把对象的排序的规则写进去
@Override
//要注意的是当返回值为0的时候,系统就会认为俩值是一样的,就不会添加该对象
public int compareTo(Student o) {
int ageNum = this.age - o.age;
int nameNum = this.name.compareTo(o.name);
//当年龄一样的时候,我们就比较俩者的姓名
return ageNum == 0 ? nameNum :ageNum;
}
HashSet<Student> hashSet = new HashSet<>();
hashSet.add(new Student("小红", 15));
hashSet.add(new Student("小王", 17));
hashSet.add(new Student("小红", 15));
System.out.println(hashSet );
}
如果自定义类不实现compareTo接口并且重写compareTo接口方法,系统将会报错
总结:1.只有HashSet集合是无序的,LinkedHashSet和TreeSet集合都是有序的。
经过实践,虽然LinkedHashSet和TreeSet集合都是有序的,但是任然不能用下标获取,添加元素!!!
2.HashSet用Hash算法来存储集合中的元素(方法底层用HashMap的方法封装);
3.LinkedHashSet用双向链表的存储结构来存储集合中的元素
4.TreeSet采用二叉树的数据结构来存储集合元素