Java学习笔记——Collection之Set

目录

一、Set相关概念

二、HashSet

LinkedHashSet

三、EnumSet

四、TreeSet

五、代码

1、HashSet

2、TreeSet

一、Set相关概念

Set:无序不可重复的集合,只能根据元素本身来访问

Set接口常用的实现类有:HashSet、LinkedHashSet、TreeSet

关于常见的类方法,总结如下:

  • HashSet
  1. 底层其实是包装了一个HashMap实现的
  2. 底层数据结构是数组+链表 + 红黑树
  3. 具有比较好的读取和查找性能, 可以有null 值
  4. 通过equalsHashCode来判断两个元素是否相等
  5. 非线程安全
  • LinkedHashSet
  1. 继承HashSet,本质是LinkedHashMap实现
  2. 底层数据结构由哈希表(是一个元素为链表的数组)和双向链表组成。
  3. 有序的,根据HashCode的值来决定元素的存储位置,同时使用一个链表来维护元素的插入顺序
  4. 非线程安全
  5. 可以有null 值
  • TreeSet
  • 底层是用TreeMap实现的,本质上是一个红黑树原理
  • 排序分两种:自然排序和自定义排序
  • 不能有null值,可通过重写Comparable接口有null值

二、HashSet

  1. HashSet是Set接口的实现类,由哈希表支持,它不保证集合的迭代顺序;
  2. Hashset允许null元素;
  3. HashSet 是无序的,即不会记录插入的顺序;
  4. HashSet 不是线程安全的, 如果多个线程尝试同时修改 HashSet,则最终结果是不确定的。 您必须在多线程访问时显式同步对 HashSet 的并发访问;

代码实例

// 初始化
HashSet language = new HashSet<>();

// 添加元素
System.out.println("------add()------");
language.add("Java");
language.add("Python");
language.add("PHP");
language.add("C++");
System.out.println(language);

language.add("Python");
System.out.println("重复的元素不添加! " + language);

// 包含
System.out.println("------contains()------");
System.out.println("contains(): " + language.contains("Java"));
System.out.println("contains(): " + language.contains("C"));

// 删除元素
System.out.println("------remove()------");
language.remove("C++");
System.out.println(language);

// for-each实现迭代
System.out.println("------元素的迭代------");
for (String l: language){
    System.out.println(l);
}
------add()------
[Java, C++, PHP, Python]
重复的元素不添加! [Java, C++, PHP, Python]
------contains()------
contains(): true
contains(): false
------remove()------
[Java, PHP, Python]
------元素的迭代------
Java
PHP
Python

LinkedHashSet

  • LinkedHashSet是HashSet的子类;
  • LinkedHashSet底层是一个LinkedHashMap,底层维护了一个 数组+双向链表;
  • LinkedHashSet 加入和取出元素的顺序一致;
  • LinkedHashSet不是线程安全的,若多线程同时访问LinkedHashSet必须加锁,或通过使用Collections.SynchronizedSet;

三、EnumSet

EnumSet的用法请看Java学习笔记——枚举_柠檬不甜会酸的博客-CSDN博客

四、TreeSet

  • TreeSet也是基于Map来实现,其底层结构为红黑树(特殊的二叉查找树);
  • TreeSet具有排序功能,分为自然排序(123456)和自定义排序两类,默认是自然排序;
  • TreeSet 继承于AbstractSet,所以它是一个Set集合,具有Set的属性和方法。
  • TreeSet 实现了NavigableSet接口,意味着它支持一系列的导航方法。比如查找与指定目标最匹配项。
  • 对插入的元素进行排序,是一个有序的集合(主要与HashSet的区别);
  • 允许插入Null值;
  • 不允许插入重复元素;
  • TreeSet是非线程安全的。

Java学习笔记——Collection之Set_第1张图片

 (1)TreeSet的创建

// TreeSet
TreeSet treeSet = new TreeSet<>();
System.out.println("TreeSet初始化容量的大小: " + treeSet.size());
TreeSet初始化容量的大小: 0

(2)添加元素

// 添加元素
treeSet.add(5);
treeSet.add(10);
treeSet.add(2);
treeSet.add(-5);
treeSet.add(3);
treeSet.add(12);
treeSet.add(100);
treeSet.add(88);
treeSet.add(99);
System.out.println("------add()------");
System.out.println("TreeSet容量大小: " + treeSet.size());
System.out.println("TreeSet元素顺序为:" + treeSet.toString());
------add()------
TreeSet容量大小: 9
TreeSet元素顺序为:[-5, 2, 3, 5, 10, 12, 88, 99, 100]

(3)删除元素

// 删除元素
treeSet.remove(-5);
System.out.println("------remove()------");
System.out.println("TreeSet元素顺序为:" + treeSet.toString());

int first = treeSet.pollFirst();
int last = treeSet.pollLast();
System.out.println("删除并返回第一个元素:如果set集合不存在元素,则返回null:" + first);
System.out.println("删除并返回最后一个元素:如果set集合不存在元素,则返回null:" + last);
System.out.println("TreeSet元素顺序为:" + treeSet.toString());
------remove()------
TreeSet元素顺序为:[2, 3, 5, 10, 12, 88, 99, 100]
删除并返回第一个元素:如果set集合不存在元素,则返回null:2
删除并返回最后一个元素:如果set集合不存在元素,则返回null:100
TreeSet元素顺序为:[3, 5, 10, 12, 88, 99]

(4)遍历

// 遍历
System.out.println("------for循环遍历------");
for (int n: treeSet){
    System.out.println(n);
}

System.out.println("------升序------");
Iterator treeAsc = treeSet.iterator();
while (treeAsc.hasNext()){
    int tmp = treeAsc.next();
    System.out.println("升序: " + tmp);
}

System.out.println("------降序------");
Iterator treeDec = treeSet.descendingIterator();
while (treeDec.hasNext()){
    int tmp = treeDec.next();
    System.out.println("降序: " + tmp);
}
------for循环遍历------
3
5
10
12
88
99
------升序------
升序: 3
升序: 5
升序: 10
升序: 12
升序: 88
升序: 99
------降序------
降序: 99
降序: 88
降序: 12
降序: 10
降序: 5
降序: 3

(5)访问

// 访问
System.out.println("------访问------");
System.out.println("头部结点: " + treeSet.first());
System.out.println("尾部结点: " + treeSet.last());
System.out.println("获取指定元素之前的所有元素集合:(不包含指定元素): " + treeSet.headSet(12));
System.out.println("获取指定元素之后的所有元素集合:(包含指定元素): " + treeSet.tailSet(12));
System.out.println("获取给定元素之间的集合:(包含头,不包含尾): " + treeSet.subSet(0, 12));
------访问------
头部结点: 3
尾部结点: 99
获取指定元素之前的所有元素集合:(不包含指定元素): [3, 5, 10]
获取指定元素之后的所有元素集合:(包含指定元素): [12, 88, 99]
获取给定元素之间的集合:(包含头,不包含尾): [3, 5, 10]

(6)判断

// 判断
System.out.println("------判断------");
System.out.println("treeSet是否为空: " + treeSet.isEmpty());
System.out.println("treeSet是否包含12: " + treeSet.contains(12));
------判断------
treeSet是否为空: false
treeSet是否包含12: true

五、代码

1、HashSet

import java.util.HashSet;

public class Day30 {
    public static void main(String[] args){
        // 初始化
        HashSet language = new HashSet<>();

        // 添加元素
        System.out.println("------add()------");
        language.add("Java");
        language.add("Python");
        language.add("PHP");
        language.add("C++");
        System.out.println(language);

        language.add("Python");
        System.out.println("重复的元素不添加! " + language);

        // 包含
        System.out.println("------contains()------");
        System.out.println("contains(): " + language.contains("Java"));
        System.out.println("contains(): " + language.contains("C"));

        // 删除元素
        System.out.println("------remove()------");
        language.remove("C++");
        System.out.println(language);

        // for-each实现迭代
        System.out.println("------元素的迭代------");
        for (String l: language){
            System.out.println(l);
        }
    }
}

2、TreeSet

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

public class Day31 {
    public static void main(String[] args){
        // TreeSet
        TreeSet treeSet = new TreeSet<>();
        System.out.println("TreeSet初始化容量的大小: " + treeSet.size());

        // 添加元素
        treeSet.add(5);
        treeSet.add(10);
        treeSet.add(2);
        treeSet.add(-5);
        treeSet.add(3);
        treeSet.add(12);
        treeSet.add(100);
        treeSet.add(88);
        treeSet.add(99);
        System.out.println("------add()------");
        System.out.println("TreeSet容量大小: " + treeSet.size());
        System.out.println("TreeSet元素顺序为:" + treeSet.toString());

        // 删除元素
        treeSet.remove(-5);
        System.out.println("------remove()------");
        System.out.println("TreeSet元素顺序为:" + treeSet.toString());

        int first = treeSet.pollFirst();
        int last = treeSet.pollLast();
        System.out.println("删除并返回第一个元素:如果set集合不存在元素,则返回null:" + first);
        System.out.println("删除并返回最后一个元素:如果set集合不存在元素,则返回null:" + last);
        System.out.println("TreeSet元素顺序为:" + treeSet.toString());

        // 遍历
        System.out.println("------for循环遍历------");
        for (int n: treeSet){
            System.out.println(n);
        }

        System.out.println("------升序------");
        Iterator treeAsc = treeSet.iterator();
        while (treeAsc.hasNext()){
            int tmp = treeAsc.next();
            System.out.println("升序: " + tmp);
        }

        System.out.println("------降序------");
        Iterator treeDec = treeSet.descendingIterator();
        while (treeDec.hasNext()){
            int tmp = treeDec.next();
            System.out.println("降序: " + tmp);
        }

        // 访问
        System.out.println("------访问------");
        System.out.println("头部结点: " + treeSet.first());
        System.out.println("尾部结点: " + treeSet.last());
        System.out.println("获取指定元素之前的所有元素集合:(不包含指定元素): " + treeSet.headSet(12));
        System.out.println("获取指定元素之后的所有元素集合:(包含指定元素): " + treeSet.tailSet(12));
        System.out.println("获取给定元素之间的集合:(包含头,不包含尾): " + treeSet.subSet(0, 12));

        // 判断
        System.out.println("------判断------");
        System.out.println("treeSet是否为空: " + treeSet.isEmpty());
        System.out.println("treeSet是否包含12: " + treeSet.contains(12));
    }
}

你可能感兴趣的:(Java,java,数据结构)