TreeSet的去重原理

本文探讨了Java中TreeSet的去重机制。在未重写Comparator时,TreeSet依赖对象的Comparable接口进行排序和去重。通过源码分析,当key为String类型时,TreeSet利用Comparable比较字母顺序,相同字母顺序的元素将不会被添加,从而实现去重功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

TreeSet去重分两种,第一种是我们重写了Comparator匿名类,第二种则是没有重写。

一,我们先分析一下没有重写的情况,当我们没有重写Comparator匿名类时

首先可以看看TreeSet的主要去重源代码

public V merge(K key, V value, BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
    Objects.requireNonNull(remappingFunction);
    Objects.requireNonNull(value);
    Entry<K,V> t = root;
    if (t == null) {
        addEntryToEmptyMap(key, value);
        return value;
    }
    int cmp;
    Entry<K,V> parent;
    // split comparator and comparable paths
    Comparator<? super K> cpr = comparator;
    if (cpr != null) {
        do {
            parent = t;
            cmp = cpr.compare(key, t.key);
            if (cmp < 0)
                t = t.left;
            else if (cmp > 0)
                t = t.right;
            else return mergeValue(t, value, remappingFunction);
        } while (t != null);
    } else {
        Objects.requireNonNull(key);
        @SuppressWarnings("unchecked")
        Comparable<? super K> k = (Comparable<? super K>) key;
        do {
            parent = t;
            cmp = k.compareTo(t.key);
            if (cmp < 0)
                t = t.left;
            else if (cmp > 0)
                t = t.right;
            else return mergeValue(t, value, remappingFunction);
        } while (t != null);
    }
    addEntry(key, value, parent, cmp < 0);
    return value;
}

可以看到上方的源代码,当我们没有重写Comparator匿名类时 ,TreeMap自身的Comparator属性就是null,赋给cpr。cpr为null,故不会执行第一个if条件语句,转而执行第二个else条件语句,也就是紫色部分,进去之后,执行到深绿色的代码时,此部分会将key向上转型成Comparable类型,因为key这个时候已经是String类型,而String类型实现了Comparable接口,所以可以用多态的方式结构实现接口的方法,往后就进入do,while循环调用String的compare方法比较字母大小,按字母的大小进行排序,如果字母大小一致,则返回0赋予cmp,cmp=0则执行红色代码块的语句。

### 配置 PyCharm 使用 Anaconda 环境并更镜像源 #### 更改 Conda 的默认通道至国内镜像源 为了提高下载速度和稳定性,在配置 PyCharm 使用 Anaconda 环境之前,可以先更改 conda 默认使用的软件仓库到清华大学开源软件镜像站。这一步骤通过命令行完成: ```bash conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/ ``` 此操作会向 `channels` 列表中添加清华的 conda-forge 渠道[^2]。 #### 创建新的 Conda 虚拟环境 接着创建一个新的 Conda 虚拟环境,并确保其中已安装 Jupyter Notebook 所需组件如 `ipykernel`: ```bash conda create -n myenv python=3.x ipykernel jupyterlab ``` 这里的 `-n myenv` 表示新环境的名字为 "myenv";而 `python=3.x` 应替为你想要的具体 Python 版本号[^1]。 #### 将新环境注册给 Jupyter Kernel 为了让 Jupyter 可识别刚建立好的 Conda 环境作为 kernel 选项之一,执行如下指令来使当前激活的新环境中包含有可用内核: ```bash python -m ipykernel install --user --name=myenv --display-name "Python (myenv)" ``` 这条语句的作用是在全局范围内将名为 “myenv” 的 Conda 环境加入到了 Jupyter notebook/kernelspecs 下面,使得可以在启动后的 Jupyter 中看到这个自定义名称对应的解释器。 #### 在 PyCharm 中配置 Anaconda 解释器 打开 PyCharm 后进入 **File -> Settings** (对于 macOS 用户则是 **PyCharm -> Preferences**) ,导航到 **Project: project_name -> Python Interpreter** 。点击右上角齿轮图标选择 **Add...**, 接着挑选 **Conda Environment -> Existing environment** 并浏览找到刚才创建的那个 Conda 环境路径下的 Python.exe 文件位置(通常位于 anaconda3/envs/myenv/python.exe)。这样就完成了在 PyCharm 内部对特定 Conda 环境的选择与应用[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值