1.

Set<String> set = new HashSet<>();
  • 1.

Set集合:添加的元素是无序、不重复、无索引。无序指的是执行一次无序,无序的顺序定下来了,再执行也是这个顺序。

HashSet:无序、不重复、无索引。

linkedHashSet:有序、不重复、无索引。

TreeSet:按照大小默认升序、不重复、无索引。

2.HashSet的底层原理

哈希值:一个int类型的数,Java中每个对象都有一个哈希值。

哈希值(Hash Value)是通过哈希函数将输入数据(如字符串、文件等)映射为固定长度的值(通常是数字)的一种结果。它在计算机科学中具有广泛的应用,包括数据存储、快速查找、数据完整性验证等。以下是一些与哈希值相关的概念和应用:

(1)哈希函数将任意长度的输入转换为固定长度的输出。理想的哈希函数具有以下特性:

  • 确定性:相同的输入始终产生相同的哈希值。
  • 快速计算:从输入计算哈希值的过程应迅速。
  • 抗碰撞性:不同的输入尽量产生不同的哈希值。
  • 均匀分布:哈希值应均匀分布,避免聚集现象。

(2)应用

  • 数据结构:如哈希表(Hash Table),利用哈希值快速查找和存储数据。
  • 数据完整性:通过对文件内容计算哈希值,验证数据在传输或存储过程中是否被修改。
  • 密码学:在安全算法中使用哈希函数保护密/码和敏感信息。
public class Main {
    public static void main(String[] args) {
        String input = "Hello, world!";
        
        // 计算哈希值
        int hashValue = input.hashCode();
        
        System.out.println("输入: " + input);
        System.out.println("哈希值: " + hashValue);
    }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.

(3)注意事项

  • 不同的哈希函数在对同一数据进行哈希时会产生不同的值。
  • 理论上,哈希值可能碰撞(即不同数据产生相同哈希值)(哈希碰撞),但理想情况下,这种情况应尽量减少。

集合框架(一)之 Set_迭代器

------------------------------------------------------------------------------------------------------------------------

集合框架(一)之 Set_迭代器_02

集合框架(一)之 Set_迭代器_03

这就是无序、不重复、无索引的原因。默认加载因子是为了之后扩容的,当占满了16*0.75=12的时候,就会扩容。

哈希表是增删改查都较好的结构。

当挂载的链表长度超过8的时候,且数组长度大于等于64时,自动将链表转为红黑树(自平衡二叉树)。


集合框架(一)之 Set_System_04

小的元素挂在左边,大的元素挂在右边。

3.深入理解HashSet

HashSet集合默认不能对内容一样的两个对象去重复。如果也需要内容去重复,可以在构造器重写hsahCode和equals方法

4.LinkedSet集合的底层原理

linkedHashSet:有序、不重复、无索引。

集合框架(一)之 Set_System_05

5.TreeSet集合的底层原理

基于红黑树

集合框架(一)之 Set_System_06

集合框架(一)之 Set_System_07

5.总结

集合框架(一)之 Set_System_08

6.注意事项

集合的并发修改异常:使用迭代器遍历集合时,又同时删除集合里的数据,程序容易发生并发修改异常的错误。

public class test {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("王麻子");
        list.add("小李子");
        list.add("李爱花");
        list.add("李爱花");
        list.add("张金霞");
        list.add("张金霞");
        list.add("张金霞");
        list.add("李玉刚");
        System.out.println(list);

        // 需求:找出集合中全部带“李”的名字,并从集合中删除。
        Iterator<String> it = list.iterator();
        while (it.hasNext()) {
            String name = it.next();
            if (name.contains("李")) {
                //list.remove(name);//会发生并发修改异常,因为迭代器遍历时,list也在修改;增强for循环和lambda表达式也不行
                it.remove();//正确的做法,使用迭代器删除元素,每删除一个数据,相当于在底层i--;for循环倒着遍历。
            }
        }
        System.out.println(list);
    }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.