IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> TreeSet 、HashSet、LinkedHashSet的特点 -> 正文阅读

[数据结构与算法]TreeSet 、HashSet、LinkedHashSet的特点

不少大公司的面试题中会问TreeSet和HashSet有什么区别。此外LinkedHashSet也是Set的一种实现类,下面归纳的是三者的特点。

????????HashSet是基于哈希表(Hash表)实现的,它不能保证线程安全,其中允许存在null元素,但null元素只能有1个。

????????当程序员向HashSet中插入一个对象时, HashSet会调用该对象的hashCode()方法(如果该对象没定义,会调用Object)来得到该对象的hashCode值;然后会根据hashCode值来决定该对象在HashSet中的存放位置,如果遇到两个对象的hashCode值一致的情况则说明它们相等, HashSet同样不会允许插入重复的元素。

????????上述描述包含了一层隐藏的含义, HashSet不能保证插入次序和遍历次序一致。

相比之下,LinkedHashSet同样是基于Hash表,它也是根据元素的hashCode值来决定元素的存储位置的,但是它同时也采用了链表的方式来保证插入次序和遍历次序一致。下面可LinketHashSetDemo.java例子看出两者的区别。


import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.Set;

public class LinkedHashSetDemo {

    public static void main(String[] args) {

        Set<String> strHashSet = new HashSet<String>();

        Set<String> strLinkedHashSet = new LinkedHashSet<String>();

        for(int i = 0; i<10; i++){

            strHashSet.add(String.valueOf(i));

            strLinkedHashSet.add(String.valueOf(i));

        }

        Iterator<String> setStringIt = strHashSet.iterator();

        while (setStringIt.hasNext())
        {
            System.out.print(setStringIt.next()+" ");
        }

        System.out.println();

        Iterator<String> linkedSetStringIt = strLinkedHashSet.iterator();

        while (linkedSetStringIt.hasNext())
        {
            System.out.print(linkedSetStringIt.next()+" ");
        }
    }
}

????????在main函数的第11- 14行中,通过for循环语句向两种集合中依次放入了1-10

????????这10个String类型的对象,然后通过迭代器,在第17~21行中通过两个while循环分别按顺序输出它们的值,结果如下。

1 3 2 1 0 7 6 5 4 9 8 
2 0 1 2 3 4 5 6 7 8 9

????????第1行是针对HashSet的输出,从中可以看到它的遍历结果和插入的次序不一致;而,第2行是针对LinkedHashSet,输出次序和插入次序一致。

TreeSet是SortedSet接口的唯一实现类,它是用二叉树存储数据的方式来保证存储的元素处于有序状态,下面来看TreeSetDemo.java例子。


import java.util.Iterator;
import java.util.Set;
import java.util.TreeSet;

public class TreeSetDemo {

    public static void main(String[] args){

        Set<String> treeSet = new TreeSet<String>();

        treeSet.add("4");

        treeSet.add("3");

        treeSet.add("1");

        treeSet.add("2");

        Iterator<String> setStringIt = treeSet.iterator();

        while(setStringIt.hasNext()){

            System.out.print(setStringIt.next() + " ");
        }
    }
}

????????在第4行中,以泛型的方式创建了一个TreeSet,并从第6-9行,以无序的方式插入了4个String对象。注意, TreeSet不允许插入null值,所以运行第10行的代码时会有异常。

????????当程序员在第14行通过迭代器遍历TreeSet对象时,会发现输出的次序和插入次序不一致,而且数据已经被排序,结果如下。

1 2 3 4 

????????如果TreeSet中存储的不是上例中的基本数据类型,而是自定义的class,那么这个类必须实现Comparable接口中的compareTo方法, TreeSet会根据compareTo中的定义来区分大小,最终确定TreeSet中的次序。

????????程序员可以在compareTo方法中定义排序依据。在前面的compareTo方法中,是以学生的id作为判断依据的,如果两个学生的id相等,那么这个方法的返回值是0,说明这两个学生是相等的(是同一个学生)。

????????此外,该方法还可以返回1或-1,其中1表示大于,-1表示小于。下面通过SortedStudent.java例子来看TreeSet是如何对自定义类进行排序的。


import java.util.Iterator;
import java.util.Set;
import java.util.TreeSet;

class SortedStudent {

    private int id;

    public SortedStudent(int id) {this.id = id;}

    public int getId(){return id;}

    public boolean equals(SortedStudent stu)
    {

        if(stu.getId() == this.id)
        {
            return true;
        }

        else {
            return false;
        }
    }



    public int compareTO(Object obj){

        if(obj instanceof SortedStudent) {

            SortedStudent s = (SortedStudent) obj;
            if(s.getId() == this.getId())
            {
                return 0;
            }
            else{
                return s.getId()>this.getId()?-1:1;
            }
        }else{

            return 0;
        }

    }


}

public class SortStudentByID{

    public static void main(String[] args){

        SortedStudent s1 = new SortedStudent(1);

        SortedStudent s2 = new SortedStudent(2);

        SortedStudent s3 = new SortedStudent(3);

        SortedStudent s4 = new SortedStudent(4);

        Set<SortedStudent> stuSet = new TreeSet<SortedStudent>();

        stuSet.add(s2);

        stuSet.add(s4);

        stuSet.add(s1);

        stuSet.add(s3);

        Iterator<SortedStudent> itStu = stuSet.iterator();
        while(itStu.hasNext()){

            System.out.println(itStu.next().getId());
        }
    }
}

在第2行定义的SortedStudent类的代码中,实现了Compareable接口。在第16行,程序员重写了compareTo方法,在这个方法中,如果两个学生对象的id相等,则认为它们相等,否则将用id的大小来判断大小。

在第38-41行中,虽然程序员用乱序的方式放入了4个学生对象,但TreeSet会自动地对它们进行排序,这可以从第46行的输出结果中得到验证。

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-12-16 17:56:08  更:2021-12-16 17:57:32 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 16:36:09-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码