`
heipark
  • 浏览: 2097706 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Java TreeSet的"陷阱"

    博客分类:
  • Java
 
阅读更多

    TreeSet基于TreeMap,它很有意思,当你执行add()方法的时候,集合会自动排序,不需要手工执行Collections.sort()进行排序,代码更加简洁(Clean),今天使用过程发现它暗藏机关,与大家分享。

 

使用TreeSet有两种方法:

一、元素实现Comparable接口,然后直接通过add方法添加元素即可。

二、创建一个Comparator,并在构造TreeSet的时候传入,如下:

 

 

//我这里Job为待添加元素
Set<Job> jobs = new TreeSet<Job>(new JobComparator());

 

我要实现的需求很简单,根据Job的优先级字段(Priority)进行排序,Job类代码如下:

 

 

public class Job implements Comparable<SortJob> {

	private String jobName;

	private Integer priority;

	public SortJob() {
	}

	public SortJob(String jobName, Integer priority) {
		this.jobName = jobName;
		this.priority = priority;
	}

	public String getJobName() {
		return jobName;
	}

	public void setJobName(String jobName) {
		this.jobName = jobName;
	}

	public Integer getPriority() {
		return priority;
	}

	public void setPriority(Integer priority) {
		this.priority = priority;
	}

	@Override
	public int compareTo(SortJob o) {
		return priority.compareTo(o.getPriority());
	}
}

 

   测试代码如下:

 

 

	@Test
	public void sortJob() {
		Set<SortJob> jobs = new TreeSet<SortJob>();

		jobs.add(new SortJob("001", 1));
		jobs.add(new SortJob("002", 1));
		jobs.add(new SortJob("003", 1));
		assertEquals(3, jobs.size());    // ①

		jobs.clear();
		jobs.add(new SortJob("001", 1));
		jobs.add(new SortJob("002", 3));
		jobs.add(new SortJob("003", 2));

		List<SortJob> listJobs = new ArrayList<SortJob>(jobs);
		assertEquals("001", listJobs.get(0).getJobName());
		assertEquals("003", listJobs.get(1).getJobName());
		assertEquals("002", listJobs.get(2).getJobName());
	}

 

    测试并没有通过,在行①,这里实际集合size为1,出了什么问题呢?

    soga,原来TreeSet的add方法会先调用Job的compareTo方法判断元素是否重复,因为Priority全部为1,所以TreeSet认为后两个Job是重复的,这样的结果显然不是我们想要的,重新实现compareTo方法如下:

 

 

	@Override
	public int compareTo(SortJob o) {
		int compare1 = priority.compareTo(o.getPriority());
		return compare1 == 0 ? this.jobName.compareTo(o.jobName) : compare1;
	}

 

再次运行测试,OK了。

 

总结:

 

  1. TreeSet通过集合元素的compareTo方法判断元素是否重复,实现compareTo方法既要考虑排序,又要考虑对象是否重复
  2. 发现这个陷阱后,发现Collections.sort()还是很不错的选择,只需要考虑排序就可以了。

 

--heipark

 

 

分享到:
评论

相关推荐

    Java Generics and Collections (Java泛型与集合)

    主要接口包括List、Set和Map,而ArrayList、LinkedList、HashSet、TreeSet、HashMap、TreeMap等是这些接口的主要实现。了解这些集合的特性和使用场景对于优化代码性能至关重要。例如,ArrayList适合于频繁的随机访问...

    java数据结构(老外那版,翻译的)

    Java的TreeMap和TreeSet实现了红黑树。 7. **堆**:一种特殊的树形数据结构,满足堆性质(最大堆或最小堆)。Java的PriorityQueue就是基于堆实现的。 8. **图**:由节点和边组成,用于表示对象之间的复杂关系。...

    java基础总结大全_java面试_java_

    - 集合框架是存储和管理对象的容器,包括List(有序,允许重复元素,如ArrayList和LinkedList)、Set(无序,不允许重复元素,如HashSet和TreeSet)和Map(键值对,如HashMap和TreeMap)。 - 迭代器(Iterator)...

    java集合框架全面进阶

    例如,了解HashMap的扩容机制、LinkedList的节点操作、ArrayList的动态数组管理等,能够帮助开发者在设计和实现自己的数据结构时避免常见陷阱。 6. **工具类**:Collections和Arrays类提供了很多实用的静态方法,如...

    java编程事项(转载收集整理版)

    Java编程事项是一个涵盖广泛的主题,它包含了众多关于Java语言编程的最佳实践、常见陷阱以及高效编程技巧。这篇由多个来源整理转贴的资料,以.htm格式呈现,旨在帮助开发者提升编程技能,避免常见错误,理解Java的...

    JAVA注意事项

    在Java编程过程中,掌握一些关键的注意事项至关重要,这不仅能提高代码质量,还能避免常见的编程陷阱。以下是一些关于"JAVA注意事项"的详细说明: 1. **命名规范**:Java有严格的命名规则,类名应使用驼峰式命名,...

    Java面试资料-高清完整PDF版(集合、IO、多线程、反射前端知识、框架).rar

    2. **集合**:Java集合框架是处理对象集合的重要工具,包括List(如ArrayList和LinkedList)、Set(如HashSet和TreeSet)、Queue(如ArrayDeque)以及Map(如HashMap和TreeMap)。学习这些数据结构的使用、特性和...

    java需要关注的知识点---好的书本

    这本书由Joshua Bloch和Neal Gafter合著,通过一系列精心设计的代码示例,揭示了Java中容易被忽视的陷阱和误解。这些谜题可以帮助开发者提高对语言规范的理解,避免写出易出错的代码。 在学习Java时,以下是一些...

    java集合迭代器Iterator中的remove陷阱

    本篇文章将深入探讨`Iterator`中的`remove`方法以及它在`List`和`Set`集合中的陷阱。 首先,`Iterator`接口提供了一个`remove()`方法,它的作用是移除当前迭代器指向的元素。在使用`Iterator`遍历集合并删除元素时...

    阿里巴巴Java开发手册 v1.4.0(详尽最新word版)

    这份手册不仅涵盖了基础的编程规范,还包括了最佳实践和陷阱提示,使得Java开发者能够在遵循规范的同时,避免常见的编程错误。 一、编程基础规范 1. 类与对象:强调单一职责原则,每个类或方法应有一个明确的责任,...

    超全Java集合框架讲解.md

    此外,深入学习集合框架的具体实现可以帮助开发者更好地利用这些工具,并避免常见的陷阱,从而提高程序的整体性能和质量。在实际开发中,合理选择合适的数据结构是非常重要的,它不仅关系到程序的执行效率,还直接...

    突破程序员基本功的16课.part2

    3.1.3 TreeMap和TreeSet 3.2 Map和List 3.2.1 Map的values()方法 3.2.2 Map和List的关系 3.3 ArrayList和LinkedList 3.3.1 Vector和ArrayList的区别 3.3.2 ArrayList和LinkedList的实现差异 3.3.3 ...

    java7源码-collection-comments:Java7集合框架源码注释

    通过深入研究这些源码注释,你可以学习到如何有效地利用Java集合框架,优化你的代码,避免常见的陷阱,并提升程序的性能。对于任何希望成为Java开发高手的人来说,理解并掌握集合框架的内部机制都是至关重要的一步。...

    java_collection_source_code_analyze:Java集合部分源码分析-Source code collection

    - `TreeSet`:基于红黑树数据结构,保持元素排序,支持快速查找和排序操作。 - **Map**:存储键值对的集合。 - `HashMap`:基于哈希表实现,提供快速的查找、插入和删除操作。 - `TreeMap`:基于红黑树实现,...

    collectionJava源码-Study_Collection:学习java集合框架

    通过研究源码,开发者不仅可以理解Java集合框架的基础操作,还能洞察其内部实现机制,这对于性能调优、避免常见陷阱以及设计自己的数据结构具有重要意义。此外,还可以学习到如何使用和扩展已有的集合类,以及如何...

    collectionJava源码-jcf-reading:JavaCollectionFramework源代码阅读。分析设计与实施

    2. **算法细节**:比如`LinkedList`插入和删除操作的时间复杂度为何是O(1),以及`TreeSet`是如何使用红黑树保证排序的。 3. **并发控制机制**:`ConcurrentHashMap`如何在不加锁的情况下实现线程安全。 4. **性能...

    “一致性相等”的陷阱

    在集合类如`TreeSet`和`TreeMap`中,这会导致元素排序和查找的问题。例如,两个被认为是不等的`Foo`对象如果在`compareTo()`中被视为相等,那么在`TreeMap`中添加这两个对象将只保留一个,而不是预期的两个独立条目...

Global site tag (gtag.js) - Google Analytics