Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Java集合(四)--treeset/treemap/章节练习题目/去重原理的解读和应用

Java集合(四)--treeset/treemap/章节练习题目/去重原理的解读和应用

作者头像
阑梦清川
发布于 2025-02-24 07:00:46
发布于 2025-02-24 07:00:46
12900
代码可运行
举报
文章被收录于专栏:学习成长指南学习成长指南
运行总次数:0
代码可运行

1.treeset结构

下面的这个就是对于这个treeset结构进行测试的一个程序,在这个里面,add表示的就是对于这个树上面进行元素的添加,打印的结果也是无序的;

image-20241019120036668
image-20241019120036668

我们之前进行这个集合选型介绍的时候,说过这个tree结构可以对于这个数据进行排序操作,这个想要实现排序的效果,需要我们自己手动传递进去一个比较器,我们上面的这个就是传递的一个匿名内部类,在这个匿名内部类里面,我们对于这个比较的规则进行了说明,上面的这个是return两个转换为这个string之后的长度相减,因此这个输出的结果就是按照长度进行排序的;

如果我们写成这个return (string) o1.compareTo((string) o2)这也写的话,就是按照这个字典序进行比较的,输出的结果也是我们的字母序的方式;

2.treemap结构

treemap是一个k-v的形式,我们想要实现这个排序的效果,也是需要对于这个里面的new对象的时候添加比较器的,我们下面的这个就是根据这个字典序进行比较,我们也可以根据上面的这个字符串的长度进行比较,也是可以的,只需要在这个对应的内部类里面进行修改就可以了;

image-20241019120844657
image-20241019120844657

下面的这个就是我们的源码里面具体是插入数据的过程:为什么这个不可以插入相同数据,主要就是我们的这个cmp是这个比较的返回值,当插入的这个key和这个已有的key一样的时候,就会cmp返回0,这样进行下面的这个分支判断的时候,就会进入这个else里面去,进而直接返回,这个就是插入相同内容不会打印的原因;

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/*
 * if (cpr != null) {
 *             do {//下面的这个就是不断地进行遍历
 *                 parent = t;
 *                 //这个地方主要就是根据这个compare方法决定的
 *                 //进行下面的这个比较,==0的时候就会直接进入else,直接return操作
 *                 //主要是我们的main方法里面的这个compare方法是如何实现的
 *                 cmp = cpr.compare(key, t.key);
 *                 //下面的这个就是不断的寻找位置的过程
 *                 if (cmp < 0)
 *                     t = t.left;
 *                 else if (cmp > 0)
 *                     t = t.right;
 *                 else {
 *                     V oldValue = t.value;
 *                     if (replaceOld || oldValue == null) {
 *                         t.value = value;
 *                     }
 *                     return oldValue;
 *                 }
 *             } while (t != null);
 * 上面第一次添加传进去的是两个一样的key,但是这个返回值不会被我们接受,
 * 这个主要是为了判断我们的这个数组是不是空的,如果是空的,这个compare方法
 * 里面就会抛异常
 */

3.集合去重辨析总结

1.hashset和treeset是如何实现去重的?

hashset:使用的就是我们的hashcode()方法和这个equals()方法,首先使用这个hashcode()方法计算这个数据在数组里面插入到的位置的索引,也就是数组的下标,然后使用这个equals()方法,但是前提是这个位置有数据,如果这个数组对应的下标没有数据,这个时候就可以直接插入数据,但是如果有数据,我们需要使用这个equals方法判断我们插入的数据和已有的数据内容(或者是属性,这个比较是程序员进行重写的,不是固定的)是不是一样的,如果不是一样的就可以进行挂载(链表需要对于这个链表进行遍历–也就是一个一个的进行比较),否则无法进行插入(这个就是去重);

treeset:如果我们传递这个compaartor匿名对象(这篇文章的第二点就是这个场景的),就是用实现的这个compare方法进行去重(我们自己设计,根据内容或者是长度,或者是其他的),使用的这个compare方法如果返回的是0,说明是相同的元素(或者是数据),这个时候就不会被添加,

如果没有传递comparator对象,则以我们添加对象实现的comparable接口的compareTo方法(string.java文件)进行去重;字符串的compareTo方法就是比较的内容;

string实现comparable接口;

4.对于arraylist的练习题目

image-20241020102047243
image-20241020102047243
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import java.util.ArrayList;
//这个主要是为了一直报警信息~~
@SuppressWarnings({"all"})
public class test {
    public static void main(String[] args) {
        
        //new出来一个arraylisy列表
        
        ArrayList arrayList = new ArrayList();
        
        //向这个列表里面添加内容,每一个内容都是一个新闻
        
        arrayList.add(new News("第一个新闻的主要的内容就是今天的天气很好,主要的内容就是今天的天气很好"));
        arrayList.add(new News("第二个新闻的主要的内容就是今天的天气很不不不不好,主要的内容就是今天的天气很好不"));
        
        //对于这个新闻内容进行遍历,使用这个size方法对于这个过程进行控制
        
        int size=arrayList.size();
        for(int i=size-1;i>=0;i--){
            //System.out.println(arrayList.get(i));
            //下面的这个是先得到我们的这个新闻对象,然后进行类型转换
            //这个主要是因为我们的这个get得到的列表类型的数据,需要转换为我们的自定义类型的对象
            News news = (News)arrayList.get(i);
            
            //下面的这个就是调用我们的成员方法对于这个新闻标题进行处理
            
            System.out.println(processTitle(news.getTitle()));
        }
    }
    
//下面的这个就是对于我们的这个新闻的长度进行处理,如果大于15,我们就会调用这个sustring方法对于这个超出的部分使用...进行表示
    
    public static String processTitle(String title){
        if(title==null){
            return "";
        }
        if(title.length()>15){
            return title.substring(0,15)+".........";
        }
        else{
            return title;
        }
    }
}
@SuppressWarnings({"all"})
class News{
    private String content;
    private String title;
//根据题目的要求,只写一个参数进行构造
    public News(String title) {
        this.title = title;
    }
//下面的这个JavaBean都是根据我们的程序员变量自动生成的
    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }
//根据题目的要求,重写这个里面的toString方法
    @Override
    public String toString() {
        return "News{" +
                "title='" + title + '\'' +
                '}';
    }
}

5.对于HashMap的练习题目

image-20241020103149266
image-20241020103149266
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package demo1;

import java.util.*;

@SuppressWarnings({"all"})
public class test {
    public static void main(String[] args) {
        //题目说了需要我们使用这个Map类型的对象,但是我的是使用Map类型的map代替了题目里面的这个m对象,就是换了名字
        Map map = new HashMap();
        //使用add方法往这个里面去添加元素
        map.put("jack",650);
        map.put("tom",1200);
        map.put("smith",2900);
        System.out.println("变化前的情况:");
        System.out.println(map);

		//我们插入相同的key但是不同的value就可以达到替换的效果
        System.out.println("替换为2600之后的情况:");
        map.put("jack",2600);
        System.out.println(map);


        Set set = map.keySet();
        for (Object key : set) {
            //这个地方需要进行向下转型
            map.put(key,(Integer)map.get(key)+100);
        }
        System.out.println("薪水加上100之后的情况:");
        System.out.println(map);

        System.out.println("=====迭代器while循环遍历员工=====");
        //entryset里面的每一个数据都是这个entry<k,v>这样的
        Set entryset = map.entrySet();
        Iterator iterator = entryset.iterator();
        while (iterator.hasNext()) {
            Map.Entry entry =  (Map.Entry)iterator.next();
            System.out.println(entry.getKey()+"-"+entry.getValue());
        }

        System.out.println("======工资======");
        //得到每一组元素里面的value并且打印输出
        Collection values = map.values();
        for (Object value : values) {
            System.out.println(value);
        }
    }
}

6.第三点的去重运用

这个下面的案例算是对于上面的这个第三点的一个去重机制的一个运用吧,可能会帮助我们对于这个去重的原理更好的理解,包括这个里面用到的方法;

这个其实是一个题目,让我们进行判断这个代码会不会报错,这个就是创建了一个treeset,然后往这个里面去进行数据的添加,但是这个会报错:

image-20241020114800488
image-20241020114800488

其实这个主要原因就是我们的这个里面没有实现comparable接口:我们可以添加这个string对象进行调试,查看这个报错的位置,就是下面的这个1569行,因为这个需要被转换为comparable接口,进而调用这个里面的compareTo方法进行比较;

image-20241020114923888
image-20241020114923888

我们的string是常用类,默认是实现了这个方法的,因此我们把这个new Person()换成string字符串都不会报错,因为这个string就实现了我们的这个comparable接口,里面也是有这个方法的,但是我们自定义的这个类person没有实现这个接口,也没有这个方法;

我们的修改方法就是在这个Person类里面去实现这个接口重写这个compareTo方法,这样的话因为return 0,因此我们的这个set里面只能添加一个数据(根据这个去重的规则)返回0,说明每一次进行比较的时候都是一样的,肯定就添加不进去了;

image-20241020120227099
image-20241020120227099

7.HashSe练习题目

image-20241020120443263
image-20241020120443263

第一次我们的print:2个对象

第二次我们的print:3个对象

第三次我们的print:4个对象

第一次,第二次添加就是正常的,但是接下来对于这个p1.name进行了修改为CC,但是这个时候删除p1是无法成功的,因为根据我们的这个1011和CC会重新计算这个索引,和原来的位置肯定是不一样的;因此我们无法成功删除;

第二次添加这个这个1001和CC貌似和原来冲了,但是我们的这个索引一定和原来的不一样,因为原来的是根据这个1011和AA计算出来的,只不过后面修改为这个CC了,但是我们的这个是使用1011和CC计算的,索引肯定和他不一样,因此可以插入,这个时候打印就是3个对象;

第三次添加这个1011,和AA和第一次的这个位置一样,但是第一次的这个已经改为这个CC了,因此我们可以添加,挂载在1011,和CC的这个后面,像链表一样串联起来~~ 法成功删除;

第二次添加这个这个1001和CC貌似和原来冲了,但是我们的这个索引一定和原来的不一样,因为原来的是根据这个1011和AA计算出来的,只不过后面修改为这个CC了,但是我们的这个是使用1011和CC计算的,索引肯定和他不一样,因此可以插入,这个时候打印就是3个对象;

第三次添加这个1011,和AA和第一次的这个位置一样,但是第一次的这个已经改为这个CC了,因此我们可以添加,挂载在1011,和CC的这个后面,像链表一样串联起来~~

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-02-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Java集合框架(二)—— HashSet、LinkedHashSet、TreeSet和EnumSet
Set接口   前面已经简绍过Set集合,它类似于一个罐子,一旦把对象'丢进'Set集合,集合里多个对象之间没有明显的顺序。Set集合与Collection基本上完全一样,它没有提供任何额外的方法。   Set集合不容许包含相同的元素,如果试图把两个相同元素加入到同一个Set集合中,则添加操作失败,add方法返回false,且新元素不会被加入。 Set判断两个对象是否相同不是使用==运算符,而是根据equals方法。也就是说,只要两个对象用equals方法比较返回true,Set就不会接受这两个对象
10JQKA
2018/05/09
1.3K0
Java集合框架(二)—— HashSet、LinkedHashSet、TreeSet和EnumSet
Java集合框架Collections
1.基本介绍: 集合就是存放对象的,他比数组好的一点就是他一开始不清楚自己长度 容器一般是分为很多种的,很多的容器在一起然后进过断的抽象和抽取就成了一个体系,我们称之为集合框架 我们看体系首先是看顶层的容器,他是底层的容器都有的特性,然后在逐步求精 最顶层的我们称之为collection 在util包中的 在collection中分为两个比较常用的子接口分别是list和set。 list是类似于数组的那种,也就是集合元素可重复,有序有脚标。 set则为无序的,所以集合元素不可重复,不可脚标查找 以下是
lwen
2018/04/17
6820
TreeSet集合的add()方法的源码解析
用TreeSet存储Integer类型数据并遍历   20,18,23,22,17,24,19,18,24 1 package cn.itcast_05; 2 3 import java.util.TreeSet; 4 5 /* 6 * TreeSet:能够对元素按照某种规则进行排序。 7 * 排序有两种方式(具体那种方式取决于使用TreeSet的构造方法) 8 * A:自然排序 9 * B:比较器排序 10 *
黑泽君
2018/10/12
6670
【Java】java 集合框架(详解)
🔥 Java集合框架 提供了一系列用于存储和操作对象组的接口和类。这些工具是为了解决不同数据结构通用操作的需求而设计的。集合框架主要包括两种类型的容器:
IsLand1314
2025/06/02
1620
【Java】java 集合框架(详解)
【Java入门提高篇】Day31 Java容器类详解(十三)TreeSet详解
  TreeSet是Set家族中的又一名懒将,跟其他两位一样,与对应的Map关系密不可分
弗兰克的猫
2018/09/03
3430
【Java入门提高篇】Day31 Java容器类详解(十三)TreeSet详解
Java基础(十九):集合框架
List除了从Collection集合继承的方法外,List 集合里添加了一些根据索引来操作集合元素的方法
Java微观世界
2025/01/21
3990
Java基础(十九):集合框架
Java集合类型大揭秘
这里HashMap里面用到链式数据结构的一个概念。上面我们提到过Entry类里面有一个next属性,作用是指向下一个Entry。打个比方,第一个键值对A进来,通过计算其key的hash得到的index=0,记做:Entry[0] = A。一会后又进来一个键值对B,通过计算其index也等于0,现在怎么办?
leon公众号精选
2022/04/27
3200
Java集合类型大揭秘
(43) 剖析TreeMap / 计算机程序的思维逻辑
40节介绍了HashMap,我们提到,HashMap有一个重要局限,键值对之间没有特定的顺序,我们还提到,Map接口有另一个重要的实现类TreeMap,在TreeMap中,键值对之间按键有序,TreeMap的实现基础是排序二叉树,上节我们介绍了排序二叉树的基本概念和算法,本节我们来详细讨论TreeMap。 除了Map接口,因为有序,TreeMap还实现了更多接口和方法,下面,我们先来看TreeMap的用法,然后探讨其内部实现。 基本用法 构造方法 TreeMap有两个基本构造方法: public Tre
swiftma
2018/01/31
9340
(43)  剖析TreeMap / 计算机程序的思维逻辑
深入Java源码剖析之Set集合
HashSet实现 Set 接口,由哈希表(实际上是一个 HashMap 实例)支持。它不保证 set 的迭代顺序;特别是它不保证该顺序恒久不变。此类允许使用 null 元素。看下面的一个例子:
wangweijun
2020/02/14
5150
Java 集合
Java 集合是一个常用的技术 ,无论是在: 开发使用,还是面试总是高频的提及到~
Java_慈祥
2024/08/06
1390
Java 集合
【数据结构】map&set详解
Set接口是一种不包含重复元素的集合。它继承自Collection接口,所以可以使用Collection所拥有的方法,Set接口的实现类主要有HashSet、LinkedHashSet、TreeSet等,它们各自以不同的方式存储元素,但都遵循Set接口的规定。
2的n次方
2024/10/15
2010
【数据结构】map&set详解
java之集合(Set、List、Map)
HashSet是Set接口的典型实现,大多数时候使用Set集合时都会使用这个实现类。我们大多数时候说的Set集合指的就是HashSet。
西西嘛呦
2020/08/26
5390
java集合类面试题_Java集合类相关面试题
java.util.Collection 是一个集合接口,Collection接口在Java类库中有非常多详细的实现。比如List、Set
全栈程序员站长
2022/09/08
2820
Java集合框架常见面试题
从下图可以看出,在 Java 中除了以 Map 结尾的类之外, 其他类都实现了 Collection 接口。
Vincent-yuan
2021/08/13
6900
Java集合框架常见面试题
Java基础之集合
-集合结构只要发生改变,迭代器必须重新获取,如果还是用的之前的迭代器,就会出现异常java.util.ConcurrentModificationException
shaoshaossm
2022/12/27
5430
Java基础之集合
Java集合框架
一、集合: 集合是Java API所提供的一系列类的实例,可以用于动态存放多个对象 为什么要使用集合?数组的长度是固定的,存满了就不能存了。集合可以存储不同类型的对象,而且它的容量可以随着对象数量的增加,自动扩大。 ----------------------------------------------------------------------------------------------------------------------------------- 二、List集合 List:存储
听着music睡
2018/05/18
2K0
Java基础-17(01)总结,TreeSet,LinkHashSet
(3)TreeSet集合 A:底层数据结构是红黑树(是一个自平衡的二叉树) B:保证元素的排序方式 a:自然排序(元素具备比较性) 让元素所属的类实现Comparable接口 package cn.itcast_05; import java.util.TreeSet; /* * TreeSet:能够对元素按照某种规则进行排序。 * 排序有两种方式 * A:自然排序 * B:比较器排序 * * TreeSet集合的特点:排序和唯一 * * 通过观察TreeSet的add()方法,
Java帮帮
2018/03/15
9210
Java知识梳理 | 详析三大集合类(附实用例程 + 实践练习题)
1.3. 常用的集合有List集合、Set集合和Map集合;   List与Set继承了Collection接口,各接口还提供了不同的实现类。 常用集合类的继承关系如下:
凌川江雪
2019/01/28
1.3K0
Java集合分类以及各自特点
常用的就是ArrayList,LinkedList,HashSet,LinkedHashSet,TreeSet,HashMap,LinkedHashMap,TreeMap; 数组和集合的区别 区别1: 数组可以存储基本数据类型/引用数据类型 基本数据类型存的是值 引用数据类型存的是地址 数组在创建的时候 就会定义存储的数据类型 也就是只能存储一种数据类型 集合只能存储引用数据类型(对象) 集合中也可以存储基本数据类型(装箱)最终存储的还是 Object 如果没有泛型限定 默认存储的都是 Object类型的数据 也就是任意类型 区别2 数组长度是固定的,不能自动增长 集合是长度可变的,根据元素的多少来决定长度
全栈程序员站长
2022/09/01
5530
Java学习笔记——Java集合
​ 在计算机科学中,算法的时间复杂度是一个函数,它定性描述了该算法的运行时间,常用O符号来表述。 ​ 时间复杂度是同一问题可用不同算法解决,而一个算法的质量优劣将影响到算法乃至程序的效率。算法分析的目的在于选择合适算法和改进算法
上分如喝水
2021/08/16
6360
Java学习笔记——Java集合
相关推荐
Java集合框架(二)—— HashSet、LinkedHashSet、TreeSet和EnumSet
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验