Set集合

Set集合中的对象不按特定的方式排序,只是简单的把对象放入集合中,但是不能包含重复对象。

Set集合由Set接口和Set接口的实现类组成,Set接口继承与于Collection接口

Set接口的实现类

Set接口常用的实现类有HashSet类和TreeSet类

  • HashSet类实现Set接口,底层实现是哈希表(HashMap)实现的,它不保证Set的迭代顺序,线程不安全,存取速度快
    • LinkedHashSet父类是HashSet,存取有序,元素不能重复
  • TreeSet类不仅实现了Set接口,还实现了SortedSet接口,因此,TreeSet类实现的Set集合在遍历结合时按照自然顺序递增排序,也可以按照指定比较器递增排序

HashSet

哈希表里存放的是哈希值,HashSet存储元素是按照哈希值来存的所以取数据也是按照哈希值取得。

HashSet底层实际上是个HashMap

AbstractCollection->AbstractSet->HashSet

   public HashSet() {

        map = new HashMap<>();

    }

  

哈希表又叫做散列表,哈希表底层是一个数组,这个数组中每一个元素是一个单向链表,每个单向链表都有一个独一无二的hash值,代表数组的下标。在某个单向链表中的每一个节点上的hash值是相同的。hash值实际上是key调用hashCode方法,再通过"hash function"转换成的值

HashSet常用方法和底层实现

    // 添加元素,调用的map的put方法

    public boolean add(E e) {

        return map.put(e, PRESENT)==null;

    }

    // 删除元素,调用map的remove方法

    public boolean remove(Object o) {

        return map.remove(o)==PRESENT;

    }

    // 判断元素是否存在

    public boolean contains(Object o) {

        return map.containsKey(o);

    }

    // 判断set是否为空 

    public boolean isEmpty() {

        return map.isEmpty();

    }

  

TreeSet

TreeSet的底层实现是TreeMap,TreeSet会自动排序,里面的元素都是有序的,根据存储元素实现的Comparable接口,重写compareTo方法来进行排序。当TreeSet的泛型对象不是java的基本类型的包装类时,对象需要重写Comparable#compareTo()方法

AbstractCollection->AbstractSet->TreeSet

    TreeSet treeSet = new TreeSet();

    treeSet.add(10);

    treeSet.add(50);

    treeSet.add(30);

    System.out.println("tree set: "+treeSet);

    // 输出 【10,30,50】

  

如果保存是自定义的类,只要实现Comparable接口就能排序

 class Person implements Comparable {

        String name;
int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
} @Override
public int compareTo(Object o) {
return this.age - ((Person) o).age;
}
} TreeSet treeSet = new TreeSet();
treeSet.add(new Person("张三", 12));
treeSet.add(new Person("李四", 45));
treeSet.add(new Person("王五", 32));
Object p = treeSet.last();
System.out.println("tree set last: " + ((Person) p).name);
// 得到的最后一个元素是年龄最大的

  

  1. 如果将compareTo()返回值写死为0,元素值每次比较,都认为是相同的元素,这时就不再向TreeSet中插入除第一个外的新元素。所以TreeSet中就只存在插入的第一个元素。
  2. 如果将compareTo()返回值写死为1,元素值每次比较,都认为新插入的元素比上一个元素大,于是二叉树存储时,会存在根的右侧,读取时就是正序排列的。
  3. 如果将compareTo()返回值写死为-1,元素值每次比较,都认为新插入的元素比上一个元素小,于是二叉树存储时,会存在根的左侧,读取时就是倒序序排列的。

TreeSet的常用方法

//返回set中第一个元素

    public E first() {

        return m.firstKey();

    }

    //返回set中最后一个元素

    public E last() {

        return m.lastKey();

    }

    //返回小于指定元素的最大的那个元素

    public E lower(E e) {

        return m.lowerKey(e);

    }

    //返回大于指定元素最小的那个元素

    public E higher(E e) {

        return m.higherKey(e);

   }

总结

HashSet与TreeSet的区别

1、HashSet与TreeSet接口的一点不同,HashSet 保存的数据是无序的,TreeSet保存的数据是有序的,所以如果要想保存的数据有序应该使用TreeSet子类。

2、利用TreeSet保存自定义类对象的时候,自定义所在的类一定要实现Comparable接口,如果没有实现这个接口那么就无法区分大小关系,而且在TreeSet中如果要进行排序,那么就要将所有的字段都进行比较,就是说在TreeSet中是依靠comparato()方法返回的是不是0来判断是不是重复元素的。

3、如果是HashSet子类,那么其判断重复数据的方式不是依靠的comparable接口而是Object类之中的两个方法:(1)取得对象的哈希码 hashCode();(2)对象比较:equals(); 这俩个方法均不需要自己编写,在eclipse里面可以使用右键source 选择自动生成。就像生成Getter 和Setter 方法一样。

最后:

TreeSet 依靠的是Comparable 来区分重复数据;

HashSet 依靠的是hashCode()、equals()来区分重复数据

Set 里面不允许保存重复数据。

java集合类-Set接口的更多相关文章

  1. Java集合类根接口:Collection 和 Map

    前言 在前文中我们了解了几种常见的数据结构,这些数据结构有着各自的应用场景,并且被广泛的应用于编程语言中,其中,Java中的集合类就是基于这些数据结构为基础. Java的集合类是一些非常实用的工具类, ...

  2. java集合类-List接口

    List接口包含List接口及List接口的所有实现类,List集合中的元素允许重复. List接口 List接口继承了Collection接口,包含Collection接口的所有方法,还定义了两个非 ...

  3. Java集合类源码解析:AbstractMap

    目录 引言 源码解析 抽象函数entrySet() 两个集合视图 操作方法 两个子类 参考: 引言 今天学习一个Java集合的一个抽象类 AbstractMap ,AbstractMap 是Map接口 ...

  4. Java集合类框架的基本接口有哪些?

    总共有两大接口:Collection 和Map ,一个元素集合,一个是键值对集合: 其中List和Set接口继承了Collection接口,一个是有序元素集合,一个是无序元素集合: 而ArrayLis ...

  5. Java集合类——Set、List、Map、Queue接口

    目录 Java 集合类的基本概念 Java 集合类的层次关系 Java 集合类的应用场景 一. Java集合类的基本概念 在编程中,常需要集中存放多个数据,数组是一个很好的选择,但数组的长度需提前指定 ...

  6. 牛客网Java刷题知识点之Java集合类里面最基本的接口有哪些

    不多说,直接上干货! https://www.nowcoder.com/ta/review-java/review?tpId=31&tqId=21086&query=&asc= ...

  7. java集合类框架的基本接口有哪些

    集合类接口指定了一组叫做元素的对象.集合类接口的每一种具体的实现类都可以以他自己的方式对元素进行保存和排序.有的集合允许重复的键,有些不允许. java集合类里面最基本 的接口: Collection ...

  8. Java集合类--温习笔记

    最近面试发现自己的知识框架有好多问题.明明脑子里知道这个知识点,流程原理也都明白,可就是说不好,不知道是自己表达技能没点,还是确实是自己基础有问题.不管了,再巩固下基础知识总是没错的,反正最近空闲时间 ...

  9. 做JavaWeb开发不知Java集合类不如归家种地

    Java作为面向对象语言对事物的体现都是以对象的形式,为了方便对多个对象的操作,就要对对象进行存储.但是使用数组存储对象方面具有一些弊端,而Java 集合就像一种容器,可以动态地把多个对象的引用放入容 ...

随机推荐

  1. ELK 日志收集系统

    传统系统日志收集的问题 在传统项目中,如果在生产环境中,有多台不同的服务器集群,如果生产环境需要通过日志定位项目的Bug的话,需要在每台节点上使用传统的命令方式查询,这样效率非常底下. 通常,日志被分 ...

  2. (三)Lucene之删除更新文档以及luke的基本使用

    一.demo 本例中采用单元测试,故在pom.xml中引入junit jar包 1.1 前提: public class IndexTest { /** *数据准备 */ private String ...

  3. (五)mybatis之一对一关系

    一.需求分析 需求:查询订单信息关联查询用户信息 分析:一条订单只能由一个消费者来下单,也就是说从订单的角度来说与消费者是一对一的关系. 二.建数据库表和实体对象 其中订单表中的字段user_id对应 ...

  4. Html5+Mui前端框架,开发记录(一)

    1.下载HBuilder X,地址:http://www.dcloud.io/hbuilderx.html,根据需求选择版本下载. Mui文档,地址:http://dev.dcloud.net.cn/ ...

  5. 关于PPP拨号 和 AT指令实现GPRS模块联网的疑问

    以下内容摘抄自互联网: ppp拨号 与 at命令的疑问 GPRS模块在Linux平台上ppp拨号上网总结与心得 以PPP拨号实现GPRS与因特网的数据通信的具体实现流程 问: 我刚接触GPRS,了解A ...

  6. Liunx-tail命令

    1. 实时刷新tail -f /var/log/messages 2. 实时刷新最新500条log tail -500f  /var/log/messages 3. tail -n 20 catali ...

  7. Windows10官方正版系统的安装、激活、升级、U盘制作,无毒无害无捆绑无风险教程

    一般电脑系统出了其他问题或电脑用久太卡了,可以选择此类方法解决系统卡顿问题,重置电脑系统或也可以恢复出厂设置 如果出现重置找不到恢复环境问题 可以通过下载系统镜像来解决,进入 MSDN 网站下载所需系 ...

  8. Python借助argv和input()制作命令行工具

    命令行执行.py文件并传递参数 代码示例如下,将参数解包 from sys import argv import requests import json import time script, us ...

  9. L1与L2正则化

    目录 过拟合 结构风险最小化原理 正则化 L2正则化 L1正则化 L1与L2正则化 参考链接 过拟合 机器学习中,如果参数过多.模型过于复杂,容易造成过拟合. 结构风险最小化原理 在经验风险最小化(训 ...

  10. TODO:AppiumTestDistribution--CapabilityManager 类

    该类代码详见git:https://github.com/AppiumTestDistribution/AppiumTestDistribution/tree/master/src/main/java ...