关于Java的TreeMap
今天写代码的时候需要做这样的一件事情
从一个文件中读取数据,得到数百万个含有time,uid,text的对象,去重之后再根据time排序
第一反应是使用TreeMap
重载了equals和hashCode方法
又继承了Comparable接口,实现了compareTo方法,只根据time做比较
结果测试的时候发现有很多数据被判定为重复直接删除了
调试了半天才发现
TreeSet的重复判定机制是直接根据compareTo方法的,如果返回0,则直接认定为重复,于是相当于只根据对象的time字段做去重与排序
附上TreeMap的put方法的源码(TreeSet的add方法会调用TreeMap的put方法)
public V put(K key, V value) { Entry<K,V> t = root;//获取红黑树的根节点 if (t == null) {//如果root为空,那么将key/value作为根节点插入 compare(key, key); // type (and possibly null) check root = new Entry<>(key, value, null); size = 1; modCount++; return null; } 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 t.setValue(value); } while (t != null); } else { if (key == null) throw new NullPointerException(); @SuppressWarnings("unchecked") Comparable<? super K> k = (Comparable<? super K>) key; do { parent = t; cmp = k.compareTo(t.key);//调用key的compareTo方法 if (cmp < 0) t = t.left; else if (cmp > 0) t = t.right; else//如果compareTo返回0,那么认为key已存在,直接更新对应的value return t.setValue(value); } while (t != null); } Entry<K,V> e = new Entry<>(key, value, parent);//建立新节点并且插入 if (cmp < 0) parent.left = e; else parent.right = e; fixAfterInsertion(e);//维护红黑树的性质 size++; modCount++; return null; }
修改方法
1. 用HashSet做去重,然后转移到List里做sort
2. 修改compareTo方法的实现,以time->uid->text的优先级做比较,只有在三个字段均相等的情况下才返回0
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· Ollama——大语言模型本地部署的极速利器
· 使用C#创建一个MCP客户端
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· Windows编程----内核对象竟然如此简单?
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用