Java基础之集合Set详解

一、概述

Set是Java中的集合类,提供了一种无顺序,不重复的集合。常用的子类包括HashSet, TreeSet等。

  • HashSet底层使用HashMap实现,根据元素的hashCode和equals来判断是否为重复元素。当元素的hashCode相同且equals返回true时则认为是重复元素。因为使用了hash算法所以HashSet有很好的添加和访问性能。可以放入null但只能放一个null
  • TreeSet底层使用红黑树实现,Set上的元素被放在一个自动排序的红黑树中。不能放入null

二、Set的常用方法

  • add() 向Set中添加元素
  • size() 返加Set的大小,即Set中元素的数量
  • remove(Object o) 从Set上删除元素
  • boolean contains(Object o) 检查Set中是否包含某个元素,包含返回true,不包含返回false
  • iterator() 返回Set的迭代器
  • clear() 清空Setis
  • Empty() 检查Set是否为空,为空返回true, 否则返回false
package collect;

import java.util.HashSet;
import java.util.Set;

/**
 * [简要描述]:Set使用
 * [详细描述]:
 *
 * @author Smalight Lv
 * @version 1.0, 2021/5/6 15:15
 * @since JDK 1.8
 */
public class SetTest1 {
    public static void main(String[] args) {
        Set<String> set =  new HashSet<>();

        //添加元素到Set
        set.add("张三");
        set.add("李四");
        set.add("王五");

        //打印Set
        System.out.println(set);

        //再加入一个王五,不能添加成功
        boolean rst = set.add("王五");
        System.out.println("添加结果:" + rst);
        System.out.println(set);

        //HashSet可以加入null,但只能加入一个null
        rst = set.add(null);
        System.out.println("添加第一个null:" + rst);
        System.out.println(set);
        rst = set.add(null);
        System.out.println("添加第二个null:" + rst);
        System.out.println(set);

        //判断Set中是否包含某个元素
        rst = set.contains("张三");
        System.out.println("是否包含元素\"张三\":" + rst);

        //删除元素
        set.remove("张三");
        System.out.println(set);

        //判断Set中是否包含某个元素
        rst = set.contains("张三");
        System.out.println("是否包含元素\"张三\":" + rst);

        //Set的大小,即Set中元素的数量
        int size = set.size();
        System.out.println("Set的大小:" + size);

        //判断Set是否为空
        boolean isEmpty = set.isEmpty();
        System.out.println("Set是否为空:" + isEmpty);

        //清空Set
        set.clear();
        System.out.println(set);

        //判断Set是否为空
        isEmpty = set.isEmpty();
        System.out.println("Set是否为空:" + isEmpty);

    }
}

运行结果:

[李四, 张三, 王五]
添加结果:false
[李四, 张三, 王五]
添加第一个null:true
[null, 李四, 张三, 王五]
添加第二个null:false
[null, 李四, 张三, 王五]
是否包含元素"张三":true
[null, 李四, 王五]
是否包含元素"张三":false
Set的大小:3
Set是否为空:false
[]
Set是否为空:true

注:TreeSet不能添加null元素,添加null时会抛出NullPointerException异常

package collect;

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

/**
 * [简要描述]: Set
 * [详细描述]:
 *
 * @author Smalight Lv
 * @version 1.0, 2021/5/6 16:28
 * @since JDK 1.8
 */
public class SetTest2 {
    public static void main(String[] args) {
        Set<String> set =  new TreeSet<>();

        //TreeSet不能加入null
        boolean rst = set.add(null);
        System.out.println("添加第一个null:" + rst);
        System.out.println(set);

    }
}

运行结果:

Exception in thread "main" java.lang.NullPointerException
 at java.util.TreeMap.compare(TreeMap.java:1294)
 at java.util.TreeMap.put(TreeMap.java:538)
 at java.util.TreeSet.add(TreeSet.java:255)
 at collect.SetTest2.main(SetTest2.java:19)

package collect;

import java.util.TreeSet;

/**
 * [简要描述]: Set
 * [详细描述]:
 *
 * @author Smalight Lv
 * @version 1.0, 2021/5/6 16:28
 * @since JDK 1.8
 */
public class SetTest3 {
    public static void main(String[] args) {
        TreeSet<String> set =  new TreeSet<>();

        //添加元素到Set
        set.add("B");
        set.add("A");
        set.add("李四");
        set.add("王五");
        set.add("张三");
        set.add("a");

        //打印Set
        System.out.println(set);

        //再加入一个王五,不能添加成功
        boolean rst = set.add("王五");
        System.out.println("添加结果:" + rst);
        System.out.println(set);

        //获取Set中的第一个元素
        System.out.println(set.first());
        //获取Set中的最后一个元素
        System.out.println(set.last());

        //判断Set中是否包含某个元素
        rst = set.contains("张三");
        System.out.println("是否包含元素\"张三\":" + rst);

        //删除元素
        set.remove("张三");
        System.out.println(set);

        //判断Set中是否包含某个元素
        rst = set.contains("张三");
        System.out.println("是否包含元素\"张三\":" + rst);

        //Set的大小,即Set中元素的数量
        int size = set.size();
        System.out.println("Set的大小:" + size);

        //判断Set是否为空
        boolean isEmpty = set.isEmpty();
        System.out.println("Set是否为空:" + isEmpty);

        //清空Set
        set.clear();
        System.out.println(set);

        //判断Set是否为空
        isEmpty = set.isEmpty();
        System.out.println("Set是否为空:" + isEmpty);

    }
}

运行结果:

[A, B, a, 张三, 李四, 王五]
添加结果:false
[A, B, a, 张三, 李四, 王五]
A
王五
是否包含元素"张三":true
[A, B, a, 李四, 王五]
是否包含元素"张三":false
Set的大小:5
Set是否为空:false
[]
Set是否为空:true

三、Set的遍历

3.1增强for循环

package collect;

import java.util.HashSet;
import java.util.Set;

/**
 * [简要描述]:增强for循环遍历Set
 * [详细描述]:
 *
 * @author Smalight Lv
 * @version 1.0, 2021/5/6 17:01
 * @since JDK 1.8
 */
public class SetTest4 {
    public static void main(String[] args) {
        Set<String> set = new HashSet<>();

        set.add("唐僧");
        set.add("孙悟空");
        set.add("猪悟能");
        set.add("沙悟净");
        System.out.println(set);

        for(String item:set){
            System.out.println(item);
        }
    }
}

运行结果:

[猪悟能, 孙悟空, 沙悟净, 唐僧]
猪悟能
孙悟空
沙悟净
唐僧

3.2 迭代器遍历

package collect;

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

/**
 * [简要描述]:增强for循环遍历Set
 * [详细描述]:
 *
 * @author Smalight Lv
 * @version 1.0, 2021/5/6 17:01
 * @since JDK 1.8
 */
public class SetTest5 {
    public static void main(String[] args) {
        Set<String> set = new HashSet<>();

        set.add("唐僧");
        set.add("孙悟空");
        set.add("猪悟能");
        set.add("沙悟净");
        System.out.println(set);

        Iterator<String> iterator = set.iterator();

        while(iterator.hasNext()){
            System.out.println(iterator.next());
        }

    }
}

运行结果:

[猪悟能, 孙悟空, 沙悟净, 唐僧]
猪悟能
孙悟空
沙悟净
唐僧

到此这篇关于Java基础之集合Set详解的文章就介绍到这了,更多相关Java集合Set内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Java集合框架源码分析之LinkedHashMap详解

    LinkedHashMap简介 LinkedHashMap是HashMap的子类,与HashMap有着同样的存储结构,但它加入了一个双向链表的头结点,将所有put到LinkedHashmap的节点一一串成了一个双向循环链表,因此它保留了节点插入的顺序,可以使节点的输出顺序与输入顺序相同. LinkedHashMap可以用来实现LRU算法(这会在下面的源码中进行分析). LinkedHashMap同样是非线程安全的,只在单线程环境下使用. LinkedHashMap源码剖析 LinkedHashM

  • Java中LinkedHashMap源码解析

    概述: LinkedHashMap实现Map继承HashMap,基于Map的哈希表和链该列表实现,具有可预知的迭代顺序. LinedHashMap维护着一个运行于所有条目的双重链表结构,该链表定义了迭代顺序,可以是插入或者访问顺序. LintHashMap的节点对象继承HashMap的节点对象,并增加了前后指针 before after: /** * LinkedHashMap节点对象 */ static class Entry<K,V> extends HashMap.Node<K,V

  • Java基础之集合框架详解

    一.前言 本节学习到的内容有以下5类,不分先后顺序: 集合Collection体系结构 List子类 与集合结合使用的迭代器对象 集合与数组的区别? 常见的一般数据结构整理 二.集合的由来? Collection List ArrayList Vector LinkedList Set hashSet treeSet 在集合没有出现之前,使用对象数组来存储对象,但是,对象数组的长度一旦确定,则不可以发生变化,所以我们希望存在一个容器就像StringBuffer一样存储字符串,同时依据传入的值的个

  • Java LinkedHashMap 底层实现原理分析

    在实现上,LinkedHashMap很多方法直接继承自HashMap,仅为维护双向链表覆写了部分方法.所以,要看懂 LinkedHashMap 的源码,需要先看懂 HashMap 的源码. 默认情况下,LinkedHashMap的迭代顺序是按照插入节点的顺序.也可以通过改变accessOrder参数的值,使得其遍历顺序按照访问顺序输出. 这里我们只讨论LinkedHashMap和HashMap的不同之处,LinkedHashMap的其他操作和特性具体请参考HashMap 我们先来看下两者的区别:

  • Java集合系列之LinkedHashMap源码分析

    这篇文章我们开始分析LinkedHashMap的源码,LinkedHashMap继承了HashMap,也就是说LinkedHashMap是在HashMap的基础上扩展而来的,因此在看LinkedHashMap源码之前,读者有必要先去了解HashMap的源码,可以查看我上一篇文章的介绍<Java集合系列[3]----HashMap源码分析>.只要深入理解了HashMap的实现原理,回过头来再去看LinkedHashMap,HashSet和LinkedHashSet的源码那都是非常简单的.因此,读

  • java HashMap,TreeMap与LinkedHashMap的详解

     java HashMap,TreeMap与LinkedHashMap的详解 今天上午面试的时候 问到了Java,Map相关的事情,我记错了HashMap和TreeMap相关的内容,回来赶紧尝试了几个demo理解下 package Map; import java.util.*; public class HashMaps { public static void main(String[] args) { Map map = new HashMap(); map.put("a", &

  • java控制台实现学生信息管理系统(集合版)

    使用java语言用集合存储数据实现学生信息管理系统,在控制台上编译执行 可以实现基本的学生信息增加.删除.修改.查询功能 IO版可以参考我的另外一篇博文. 运行界面如下 欢迎界面 添加学生信息 删除学生信息 修改学生信息 查询学生信息 退出系统 系统模块结构图 系统业务流程图 代码如下 Student类 public class Student { private String stuNo; private String name; private int age; public Student

  • 详解Java中LinkedHashMap

    初识LinkedHashMap 大多数情况下,只要不涉及线程安全问题,Map基本都可以使用HashMap,不过HashMap有一个问题,就是迭代HashMap的顺序并不是HashMap放置的顺序,也就是无序.HashMap的这一缺点往往会带来困扰,因为有些场景,我们期待一个有序的Map. 这个时候,LinkedHashMap就闪亮登场了,它虽然增加了时间和空间上的开销,但是通过维护一个运行于所有条目的双向链表,LinkedHashMap保证了元素迭代的顺序. 四个关注点在LinkedHashMa

  • Java源码解析之LinkedHashMap

    一.成员变量 先来看看存储元素的结构吧: static class Entry<K,V> extends HashMap.Node<K,V> { Entry<K,V> before, after; Entry(int hash, K key, V value, Node<K,V> next) { super(hash, key, value, next); } } 这个Entry在HashMap中被引用过,主要是为了能让LinkedHashMap也支持树化.

  • Java使用LinkedHashMap进行分数排序

    分数排序的特殊问题 在java中实现排序远比C/C++简单,我们只要让集合中元素对应的类实现Comparable接口,然后调用Collections.sort();方法即可. 这种方法对于排序存在许多相同元素的情况有些浪费,明显即使值相等,两个元素之间也要比较一下,这在现实中是没有意义的. 典型例子就是学生成绩统计的问题,例如高考中,满分是150,成千上万的学生成绩都在0-150之间,平均一个分数的人数成百上千,这时如果排序还用传统方法明显就浪费了. 进一步思考 成绩既然有固定的分数等级,我们可

随机推荐