哈希表是一种数据结构,能够快速定位已存储的数据的地址:
1.通过hashCode()计算哈希码,通过该哈希码定位到内存地址。hash码的计算通常基于对象的某些特有属性进行计算;
2.如果地址不同,则直接存入;
3.如果地址相同,则调用该对象的equals()比较内容;如果内容相同,则丢弃,不同,则顺延一个空间,存入。
HashSet HashMap 都是基于hash表的数据结构进行实现的。
HashSet确保对象唯一,通过hashCode()与equals()来完成
hashCode() 计算不同对象的哈希码
equals() 当地址相同时,判断对象是否相同,如果相同,则丢弃,如果不同,就顺延存入。这样便确保了对象的唯一性
public class Person { private String name; private int age; public Person() { super(); } public Person(String name, int age) { super(); this.name = name; this.age = age; } public Person(String name) { super(); this.name = name; } /** * Person对象的哈希值计算方法 */ @Override public int hashCode() { return name.hashCode()+age*31; } /** * 比较Person对象是否相同的规则 */ @Override public boolean equals(Object obj) { Person p = (Person)obj; return this.name.equals(p.getName()) && this.age == p.getAge(); } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } }
public static void main(String[] args) { Set<Person> set = new HashSet<Person>(); set.add(new Person("zs1",10)); set.add(new Person("zs2",20)); set.add(new Person("zs3",30)); set.add(new Person("zs1",10));//hachCode()结果相同,equals()结果为true,该对象被丢弃 Iterator<Person> iter = set.iterator(); while(iter.hasNext()) { Person p = iter.next(); System.out.println(p.getName()+"--"+p.getAge()); } }
TreeSet确保对象唯一,并且按指定规则排序,通过compare()或compareTo()实现
TreeSet中比较器,返回int值,如果为0,表示相同,则不存,确保唯一。
TreeSet的实现,不依赖hashCode()和equals()。
如,String字符串类实现了Comparable接口,复写了compareTo()
public int compareTo(String anotherString) { int len1 = value.length; int len2 = anotherString.value.length; int lim = Math.min(len1, len2); char v1[] = value; char v2[] = anotherString.value; int k = 0; while (k < lim) { char c1 = v1[k]; char c2 = v2[k]; if (c1 != c2) { return c1 - c2; //比较字符的自然顺序 } k++; } return len1 - len2; }
1. 自定义比较器,实现Comparator接口;在存入TreeSet集合的时候指定比较器。
让集合具备比较功能,而且将覆盖元素自身的比较规则!
应用场景:
a.覆盖对象本身具备的比较规则,如String类默认按自然顺序排序,将其覆盖为按长度排序
b.为其它类(非自己创建的类)指定比较规则,将比较功能传入集合中,让集合具备比较功能
public class Person { private String name; private int age; public Person() { super(); } public Person(String name, int age) { super(); this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } }
import java.util.Comparator; public class PersonComparator implements Comparator<Person> { /** * 姓名不同 * 存入,并按姓名排序 * 姓名相同,比较年龄 * 年龄不同,则首先按姓名,再按年龄排序 * 年龄也相同,则为同一个对象,不存! */ @Override public int compare(Person o1, Person o2) { //1.按姓名比较 int comp = o1.getName().compareTo(o2.getName()); //2.姓名相同,则继续按年龄比较,如果年龄相同,则表示同一个对象,不存! return comp==0?(o1.getAge()-o2.getAge()):comp; } }
public static void main(String[] args) { Set<Person> set = new TreeSet<Person>(new PersonComparator());//传入比较器 set.add(new Person("zs1",10)); set.add(new Person("zs2",20)); set.add(new Person("zs2",15));//姓名相同的情况下,则年龄作为次要排序条件 set.add(new Person("zs1",10));//哈希值相同,equals()结果为true,该对象被丢弃 Iterator<Person> iter = set.iterator(); while(iter.hasNext()) { Person p = iter.next(); System.out.println(p.getName()+"--"+p.getAge()); } }
结果:
zs1--10 zs2--15 zs2--20
2. 实现Comparable接口
public class Person implements Comparable<Person>{ private String name; private int age; public Person() { super(); } public Person(String name, int age) { super(); this.name = name; this.age = age; } /** * 排序规则: * 首先按姓名排 * 姓名相同,再按年龄排 * 年龄也相同,则为同一个对象,不存! */ @Override public int compareTo(Person o) { int temp = this.name.compareTo(o.getName()); return temp==0 ? (this.age-o.getAge()) : temp; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } }
public static void main(String[] args) { Set<Person> set = new TreeSet<Person>(); set.add(new Person("zs1",10)); set.add(new Person("zs2",20)); set.add(new Person("zs2",15));//姓名相同的情况下,再按年龄排序 set.add(new Person("zs1",10));//哈希值相同,equals()结果为true,该对象被丢弃 Iterator<Person> iter = set.iterator(); while(iter.hasNext()) { Person p = iter.next(); System.out.println(p.getName()+"--"+p.getAge()); } }结果:
相关推荐
`HashSet`基于哈希表,提供了快速的插入、删除和查找,而`TreeSet`则保证元素的排序,适用于需要排序的场景。`Comparator`接口则允许我们自定义排序规则,增强了集合的灵活性。理解并熟练运用这些概念和工具,对于...
HashSet和TreeSet是Java集合框架中的两种重要数据结构,它们都是Set接口的实现类,用于存储不重复的元素。在编程实践中,理解它们的区别和应用场景至关重要。 HashSet是基于HashMap实现的,它不保证元素的顺序,...
在Java编程语言中,集合框架提供了多种数据结构来存储和操作数据,其中`TreeMap`、`TreeSet`、`HashSet`以及`HashMap`是最常用的数据结构之一。这些集合类各自有着独特的特性和应用场景,下面将对它们进行详细介绍。...
HashSet 和 TreeSet 是 Java 中两个常用的集合类,它们都实现了 Set 接口,但它们之间有很大的区别。本文将详细介绍 HashSet 和 TreeSet 的区别,帮助大家更好地理解和使用这些集合类。 HashSet HashSet 是一个...
HashSet 和 TreeSet 是 Java 中两种常用的 Set 集合实现,它们都继承自 Set 接口,但实现方式和特性上存在显著差异。 首先,HashSet 是基于哈希表(HashMap 实例)来存储元素的,因此它提供了快速的插入、删除和...
在Java编程中,HashMap、HashSet、TreeMap和TreeSet是四种常见的集合类,它们各自有特定的用途和内部实现机制。这些数据结构用于存储和管理数据,其中HashMap和HashSet是基于哈希表实现的,而TreeMap和TreeSet则是...
`Set`接口不包含重复元素,其主要实现有`HashSet`(基于哈希表,不允许重复元素)和`TreeSet`(基于红黑树,提供排序功能)。`HashSet`提供了快速的查找,而`TreeSet`则保证了元素的排序。 `Queue`接口用于表示先进...
本资源聚焦于Java集合中的四个关键类:HashSet、TreeSet、HashMap和TreeMap,它们分别代表了不同类型的集合容器。 1. **HashSet**:HashSet是一个不允许重复元素的无序集合。它基于哈希表实现,插入和查找操作的...
本篇文章将详细讲解Java中的基本集合类ArrayList、LinkedList和Vector,以及HashSet和TreeSet。 1. ArrayList ArrayList是基于动态数组实现的集合类,它允许存储重复元素。默认初始容量为10,当添加元素超过容量时...
以上内容涵盖了Java中集合操作的基本概念和常见用法,对于初学者来说,理解和掌握这些知识点是学习Java编程的基础。通过实际编程练习和参考相关PPT材料,可以更深入地理解这些概念并提高编程能力。
Java集合框架是Java编程语言中一个非常重要的组成部分,它提供了一组高级的数据结构,使得开发者能够更方便地管理和操作对象。在本次实验中,我们主要关注了三个主要的集合接口:Set、List和Map,以及它们的一些常见...
- `HashSet` 是基于哈希表的无序集合,不允许有重复元素,不保证元素顺序。 - `TreeSet` 基于红黑树,自动保持元素的排序,可按照自然顺序或自定义比较器进行排序。 5. `java.util.Date` 和 `java.time` 包: - ...
哈希表(HashTable)是计算机科学中一种非常重要的...熟悉不同编程语言中的哈希表实现,如Python的dict、C++的unordered_map和Java的HashMap,以及在面对冲突时如何有效地管理这些数据结构,将有助于在面试中脱颖而出。
HashSet 是一种基于哈希表实现的 Set 集合,LinkedHashSet 是一种基于链表实现的 Set 集合,TreeSet 是一种基于树形结构实现的 Set 集合。 Map 集合 Map 集合是一种键值对的集合,元素是键值对的形式,键是唯一的...
Java集合框架是Java编程语言中的一个核心组成部分,它为数据存储和操作提供了丰富的接口和类。在本篇中,我们将深入探讨Java集合的排序机制以及集合类的详细使用。 首先,我们来了解一下Java集合的基本分类。Java...
通过阅读源码,我们可以看到HashSet在添加元素时,如何利用哈希表进行查找和比较,以及如何处理冲突。同时,源码分析也能帮助我们理解HashMap的扩容机制,以及为什么即使两个对象的hashCode相同,它们仍然可以在...
HashSet是一个基于哈希表的实现,TreeSet是一个基于红黑树的实现。Set接口的常用方法包括add、remove、contains等。 Map接口继承自Object接口,它定义了一个键值对集合。Map接口有两个主要实现类:HashMap和...
`HashSet`是最基础的实现,无序且不允许重复,基于哈希表实现;`TreeSet`遵循排序规则,提供了排序功能;`LinkedHashSet`保持了元素插入时的顺序。 3. `Queue`接口:`LinkedList`也可以作为`Queue`的实现,此外还有...