Set接口
Set接口继承自Collection,Set接口中没有新增方法,方法和Collection保持完全一致。我们在前面通过List学习的方法,在Set中仍然试用。因此,学习Set的使用将没有任何难度。
Set容器表示:无序、不可重复。无序表示Set中的元素没有索引,我们只能遍历查找;不可重复表示:不允许加入重复的元素。更确切地讲,新元素如果和Set中某个元素通过equals()方法比对为true,则不能加入;甚至,Set中也只能放入一个null元素,不能多个。
Set常用的实现类有:HashSet、TreeSet等,我们一般使用HashSet。
HashSet基本使用
大家在做下面练习时,重点体会“Set是无序、不可重复”的核心要点。
【示例1】HashSet的使用
public class TestSet01 {
public static void main(String[] args) {
Set<String> s = new HashSet<String>();
s.add ("hello");
s.add ("world");
System.out.println(s);
s.add ("hello"); // 相同的元素不会被加入
System.out.println (s);
s.add(null);
System.out.println(s);
s.add(null);
System.out.println(s);
}
}
示例1 运行效果图
HashSet底层实现
HashSet是采用哈希算法实现,底层实际是用HashMap实现的(HashSet本质就是一个简化版的HashMap),因此,查询效率和增删效率都比较高。
我们打开JDK中HashSet的源码:
public class HashSet<E> implements Set<E>, Cloneable, java.io.Serializable {
private transient HashMap<E, Object> map;
private static final Object PRESENT = new Object();
public HashSet() {
map = new HashMap<E, Object>();
}
public boolean add(E e) {
return map.put(e, PRESENT) == null;
}
//多余代码,省略
}
我们发现里面有个map属性,这就是HashSet的核心秘密。我们再看add()方法,发现增加一个元素说白了就是在map中增加一个键值对,键对象就是这个元素,值对象是名为PRESENT的Object对象。说白了,就是“往set中加入元素,本质就是把这个元素作为key加入到了内部的map中”。
由于map中key都是不可重复的,因此,Set天然具有“不可重复”的特性。
TreeSet的使用和底层实现
TreeSet底层实际是用TreeMap实现的,内部维持了一个简化版的TreeMap,通过key来存储Set的元素。 TreeSet内部需要对存储的元素进行排序,因此,我们对应的类需要实现Comparable接口。这样,才能根据compareTo()方法比较对象之间的大小,才能进行内部排序。
【示例2】 TreeSet和Comparable接口使用
public class Test {
public static void main(String[] args) {
User u1 = new User(1001,"高淇",18);
User u2 = new User(2001,"高希希",5);
Set<User> set = new TreeSet<User>();
set.add(u1);
set.add(u2);
}
}
class User implements Comparable<User>{
int id;
String uname;
int age;
public User(int id, String uname,int age) {
this.id = id;
this.uname = uname;
this.age = age;
}
/**
* 返回0 表示 this == obj
返回正数表示 this > obj
返回负数表示 this < obj
*/
@Override
public int compareTo(User o) {
if(this.id>o.id){
return 1;
}else if(this.id<o.id){
return -1;
}else {
return 0;
}
}
}
使用TreeSet要点:
1. 由于是二叉树,需要对元素做内部排序。 如果要放入TreeSet中的类没有实现Comparable接口,则会抛出异常:java.lang.ClassCastException
2. TreeSet中不能放入null元素
「全栈Java笔记」是一部能帮大家从零到一成长为全栈Java工程师系列笔记。笔者江湖人称 Mr. G,10年Java研发经验,曾在神州数码、航天院某所研发中心从事软件设计及研发工作,从小白逐渐做到工程师、高级工程师、架构师。精通Java平台软件开发,精通JAVAEE,熟悉各种流行开发框架。
笔记包含从浅入深的六大部分:
A-Java入门阶段
B-数据库从入门到精通
C-手刃移动前端和Web前端
D-J2EE从了解到实战
E-Java高级框架精解
F-Linux和Hadoop
网友评论