博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java集合:Set接口总结
阅读量:6374 次
发布时间:2019-06-23

本文共 5499 字,大约阅读时间需要 18 分钟。

  hot3.png

Set 集合不允许包含相同的元素,如果试把两个相同的元素加入同一个 Set 集合中,则添加操作失败。

Set 判断两个对象是否相同不是使用 == 运算符,而是根据 equals 方法。

Set实现类:HashSet、LinkedHashSet、TreeSet

HashSet:通过散列表存信息,无序存储,元素必须定义hashCode();

LinkedHashSet:内部使用链表维护元素顺序,按顺序插入顺序排序,也必须定义hashCode();

TreeSet:通过树结构(和TreeMap一致,使用红黑树)存储元素,存储数据有序。

HashSet :

1、当向 HashSet 集合中存入一个元素时,HashSet 会调用该对象的 hashCode() 方法来得到该对象的hashCode 值, 然后根据 hashCode 值决定该对象在 HashSet 中的存储位置。

2、如果两个元素的 equals() 方法返回 true,但它们的 hashCode() 返回值不相等,hashSet 将会把它们存储在不同的位置,但依然可以添加成功。

3、HashSet 集合判断两个元素相等的标准:两个对象通过 equals() 方法比较相等,并且两个对象的hashCode() 方法返回值也相等。即:如果两个对象通过 equals() 方法返回 true,这两个对象的hashCode 值也应该相同。

重写 hashCode() 方法的基本原则:

1、在程序运行时,同一个对象多次调用 hashCode() 方法应该返回相同的值。

2、当两个对象的 equals() 方法比较返回 true 时,这两个对象的 hashCode() 方法的返回值也应相等。

3、对象中用作 equals() 方法比较的 Field,都应该用来计算 hashCode 值。

 

LinkedHashSet :

1、LinkedHashSet 是 HashSet 的子类。

2、LinkedHashSet 集合根据元素的 hashCode 值来决定元素的存储位置,但它同时使用链表维护元素的次序,这使得元素看起来是以插入顺序保存的。

3、LinkedHashSet 性能插入性能略低于 HashSet,但在迭代访问 Set 里的全部元素时有很好的性能。

4、LinkedHashSet 有序但不允许集合元素重复。

 

TreeSet:

TreeSet 是 SortedSet 接口的实现类,TreeSet 可以确保集合元素处于排序状态。

TreeSet 支持两种排序方法:自然排序和定制排序。默认情况下,TreeSet 采用自然排序。

排序:

1、TreeSet 会调用集合元素的 compareTo(Object obj) 方法来比较元素之间的大小关系,

     然后将集合元素按升序排列。

2、如果试图把一个对象添加到 TreeSet 时,则该对象的类必须实现 Comparable 接口。

3、实现 Comparable 的类必须实现 compareTo(Object obj) 方法,两个对象即通过

    compareTo(Object obj)方法的返回值来比较大小。

注意:

向 TreeSet 中添加的应该是同一个类的对象,

当需要把一个对象放入 TreeSet 中,重写该对象对应的 equals() 方法时,应保证该方法与

compareTo(Object obj) 方法有一致的结果:即如果两个对象通过 equals() 方法比较返回 true,

则通过 compareTo(Object obj) 方法比较应返回 0。

自然排序:

import java.util.*;/* TreeSet:可以对Set集合中的元素进行排序。	 底层数据结构是二叉树。	 保证元素唯一性的依据:	 compareTo方法return 0.	 TreeSet排序的第一种方式:让元素自身具备比较性。	 元素需要实现Comparable接口,覆盖compareTo方法。	 也种方式也成为元素的自然顺序,或者叫做默认顺序。	 TreeSet的第二种排序方式。	 当元素自身不具备比较性时,或者具备的比较性不是所需要的。	 这时就需要让集合自身具备比较性。	 在集合初始化时,就有了比较方式。 需求: 往TreeSet集合中存储自定义对象学生。 想按照学生的年龄进行排序。 记住,排序时,当主要条件相同时,一定判断一下次要条件。 */class Treeset {	public static void main(String[] args) {		Set ts = new TreeSet();		ts.add(new Student("lisi02", 22));		ts.add(new Student("lisi007", 20));		ts.add(new Student("lisi09", 19));		ts.add(new Student("lisi08", 19));		// ts.add(new Student("lisi007",20));		// ts.add(new Student("lisi01",40));		Iterator it = ts.iterator();		while (it.hasNext()) {			Student stu = (Student) it.next();			System.out.println(stu.getName() + "..." + stu.getAge());		}	}}class Student implements Comparable// 该接口强制让学生具备比较性。{	private String name;	private int age;	Student(String name, int age) {		this.name = name;		this.age = age;	}	public int compareTo(Object obj) {		// return 0;		if (!(obj instanceof Student))			throw new RuntimeException("不是学生对象");		Student s = (Student) obj;		System.out.println(this.name + "....compareto....." + s.name);		if (this.age > s.age)			return 1;		if (this.age == s.age) {			return this.name.compareTo(s.name);		}		return -1;	}	public String getName() {		return name;	}	public int getAge() {		return age;	}}

定制排序:

import java.util.*;/*当元素自身不具备比较性,或者具备的比较性不是所需要的。这时需要让容器自身具备比较性。定义了比较器,将比较器对象作为参数传递给TreeSet集合的构造函数。当两种排序都存在时,以比较器为主。定义一个类,实现Comparator接口,覆盖compare方法。*/class Student implements Comparable//该接口强制让学生具备比较性。{    private String name;    private int age;    Student(String name,int age)    {        this.name = name;        this.age = age;    }    public int compareTo(Object obj)    {        //return 0;        if(!(obj instanceof Student))            throw new RuntimeException("不是学生对象");        Student s = (Student)obj;        //System.out.println(this.name+"....compareto....."+s.name);        if(this.age>s.age)            return 1;        if(this.age==s.age)        {            return this.name.compareTo(s.name);        }        return -1;    }    public String getName()    {        return name;    }    public int getAge()    {        return age;    }}class TreeSetDemo2 {    public static void main(String[] args)     {        Set ts = new TreeSet();        ts.add(new Student("lisi02",22));        ts.add(new Student("lisi02",21));        ts.add(new Student("lisi007",20));        ts.add(new Student("lisi09",19));        ts.add(new Student("lisi06",18));        ts.add(new Student("lisi06",18));        ts.add(new Student("lisi007",29));        //ts.add(new Student("lisi007",20));        //ts.add(new Student("lisi01",40));        Iterator it = ts.iterator();        while(it.hasNext())        {            Student stu = (Student)it.next();            System.out.println(stu.getName()+"..."+stu.getAge());        }    }}class MyCompare implements Comparator{    public int compare(Object o1,Object o2)    {        Student s1 = (Student)o1;        Student s2 = (Student)o2;        int num = s1.getName().compareTo(s2.getName());        if(num==0)        {            return new Integer(s1.getAge()).compareTo(new Integer(s2.getAge()));            /*            if(s1.getAge()>s2.getAge())                return 1;            if(s1.getAge()==s2.getAge())                return 0;            return -1;            */        }        return num;    }}

性能分析:可以参考《Thinking in java》,数据如下:

------------- TreeSet -------------

 size       add  contains   iterate
   10      1316       506       180
  100       199       101        22
 1000       250       174        19
10000       266       224        21
------------- HashSet -------------
 size       add  contains   iterate
   10      1717       325       242
  100        59        16        43
 1000        66        25        27
10000        66        28        25
---------- LinkedHashSet ----------
 size       add  contains   iterate
   10       516       151        72
  100       127        40        29
 1000       145        57        27
10000       125        53        25

可以看出HashSet性能基本总比TreeSet好 ,除非确定需要排序时,才该使用TreeSet。

 

该博客仅作为复习记录。

本文大多数参考:http://www.cnblogs.com/shellway/p/3709074.html

转载于:https://my.oschina.net/eager/blog/718013

你可能感兴趣的文章
利用MapReduce计算平均数
查看>>
scala-05-map映射
查看>>
Spring Boot - how to configure port
查看>>
右键添加复制路径选项
查看>>
DocFetcher 本机文件搜索工具
查看>>
ambassador 学习三 限速处理
查看>>
HTTP传输编码增加了传输量,只为解决这一个问题 | 实用 HTTP
查看>>
家里蹲大学数学杂志期刊模式目录
查看>>
数据结构:最小生成树--Kruskal算法
查看>>
Swift_1_基本数据类型
查看>>
POJ 1849 Two(遍历树)
查看>>
Recurrent Neural Network[CTC]
查看>>
VS注释与取消注释快捷键
查看>>
深入解析Vuex实战总结
查看>>
.NET编译项目时出现《此实现不是 Windows 平台 FIPS 验证的加密算法的一部分》处理方法...
查看>>
流水落花春去也
查看>>
从.NET中委托写法的演变谈开去(下):性能相关
查看>>
C# 多人聊天程序
查看>>
【教训】为什么不作备份?!
查看>>
网搜索引擎架构设计
查看>>