目录
1.无序&&唯一
2.真的唯一么?
3.先入为主
4.Set的其他实现类
HashSet实现了Set接口,内部主要是通过HashMap实现的.
1.无序&&唯一
public class HashSetDemo1 { public static void main(String[] args) { HashSet<String> set = new HashSet<>(); String[] str = new String[] { "collection", "list", "set", "itaretor", "map", "set" }; Collections.addAll(set, str); System.out.println(set); } }
运行结果:[set, itaretor, collection, list, map]
可以看到,set的打印顺序与数组str不同,且重复"set"只能存储一次,那么HashSet是如何判断两个对象是否是同一个对象的呢?
2.真的唯一么?
在HashMap内部对于是否是同一个对象是这样判断的:
(p.hash == hash && ((k = p.key) == key || (key != null && key.equals(k))));
与三个条件有关:1st.判断hash;2nd.判断==;3rd.调用equals(),即如果(1st && (2nd || 3rd))满足true,则视为对象.可见HashSet内元素的唯一并非真正意义上的唯一,而是取决于如何定义hashCode()和equals()方法.下面依次进行验证.
1)判断hashCode()
public class HashSetDemo2 { public static void main(String[] args) { HashSet<Person> set = new HashSet<>(); Person p1 = new Person("小明"); Person p2 = new Person("小明"); set.add(p1); set.add(p2); System.out.println(set.size()); } } class Person { String name; public Person(String name) { this.name = name; } @Override public int hashCode() { int code = super.hashCode(); System.out.println("hashCode被执行:" + code); return code; } }
运行结果:
hashCode被执行:366712642
hashCode被执行:1829164700
2
由结果可知hashCode()方法被执行,由于hash值不同,p2可以添加到set中.注意:不要在添加元素之后尝试修改HashSet当中参与生成hash值的属性,否则hash值的改变会导致很多问题.
2)判断"=="
当hashCode相等时,会通过==判断两个对象是否是同一个对象,如果是同一个将不会再进行equals判断(短路||).
public class HashSetDemo2 { public static void main(String[] args) { HashSet<Person> set = new HashSet<>(); Person p1 = new Person("小明"); set.add(p1); set.add(p1); System.out.println(set.size()); } } class Person { String name; public Person(String name) { this.name = name; } @Override public int hashCode() { System.out.println("hashCode被执行"); return 1; } @Override public boolean equals(Object o) { System.out.println("equals被执行"); return true; } }
运行结果:
hashCode被执行
hashCode被执行
1
注意,此段代码中的equals()未被调用.
3)调用equals判断
当两个对象hashCode相等但又不是同一个对象,将调用equals方法再次进行判断:如果true则视为同一个对象,否则视为两个对象(hash值冲突).
public class HashSetDemo2 { public static void main(String[] args) { HashSet<Person> set = new HashSet<>(); Person p1 = new Person("小明"); Person p2 = new Person("小明"); set.add(p1); set.add(p2); System.out.println(set.size()); } } class Person { String name; public Person(String name) { this.name = name; } @Override public int hashCode() { System.out.println("hashCode被执行"); return 1; } @Override public boolean equals(Object o) { System.out.println("equals被执行"); return false; } }
运行结果:
hashCode被执行
hashCode被执行
equals被执行
2
如果上面equals返回true,则打印出的set.size()为1.
3.先入为主
HashSet在添加元素时,如果认定了重复元素,HashSet将遵循先入为主的原则,直接舍弃新元素.例:
public class HashSetDemo3 { public static void main(String[] args) { HashSet<Person> set = new HashSet<>(); Person p1 = new Person("小明"); Person p2 = new Person("小红"); set.add(p1); set.add(p2); System.out.println(set); } } class Person { String name; public Person(String name) { this.name = name; } @Override public int hashCode() { return 1; } @Override public boolean equals(Object o) { return true; } @Override public String toString() { return name; } }
运行结果:[小明]
4.Set的其他实现类
1)TreeSet
内部通过二叉树结构存储数据,排序存储,可在构造时自定义Comparator按指定规则存储.
相关推荐
Java集合框架是Java编程语言中一个非常重要的组成部分,它为开发者提供了存储和操作对象的统一接口和类。这个框架使得处理各种数据结构变得更加方便和高效。在这个“java集合框架的使用”主题中,我们将深入探讨如何...
Java集合框架是Java编程语言中的一个核心组成部分,它为数据存储和操作提供了丰富的类库。在Java中,集合框架主要包括接口(如List、Set、Queue)和实现这些接口的类(如ArrayList、HashSet、LinkedList等)。这个...
在使用泛型类时,需要在类名后面添加“<>”并指定具体的类型,例如:`ShowObject<Dog> showDog = new ShowObject<Dog>();` 泛型接口的声明使用“interface 名称 < 泛型列表 >”的格式,例如:`interface Listen<E> ...
- 集合框架如ArrayList、LinkedList、HashSet等都支持泛型,可以指定元素类型,如`List<String>`。 - 泛型集合不允许存储null(除了null是类的实例,如`List<Class<?>>`)。 6. 泛型和多态: - 泛型类的子类可以...
首先,Java集合框架是一个统一的架构,它提供了多种接口和类,使得我们可以方便地处理各种数据结构。核心的接口包括Collection、List、Set和Map。Collection是最基础的接口,它有多个子接口,例如: 1. **List<E>**...
Java集合框架中的Set接口是Java编程中不可或缺的一部分,主要用于存储不允许重复的元素。Set接口继承了Collection接口,因此它具备了Collection接口的所有基本操作。同时,Set接口还提供了特有的方法,如添加元素、...
### Java集合框架的主要接口和类全解析 #### Java集合框架概览 Java集合框架是Java标准库的一个核心组成部分,它为开发人员提供了多种用于存储和操作数据的方式。这些集合类和接口的设计旨在满足不同的需求,并...
Java集合框架是Java编程语言中的一个重要组成部分,它提供了多种数据结构,如列表、队列、集、映射等,方便程序员存储和管理对象。本篇文章将详细讲解Java中的基本集合类ArrayList、LinkedList和Vector,以及HashSet...
Java集合框架常见面试题 Java集合框架是Java语言中最为重要的框架之一,Java集合框架提供了许多常用的数据结构和算法,以方便开发者快速高效地进行编程。在Java集合框架中,存在着各种不同的集合类型,每种集合类型...
虽然Java比C#晚引入泛型,但从Java 5开始,它也提供了丰富的泛型集合框架。一些主要的Java泛型集合包括: 1. `ArrayList<E>`:与C#的`List<T>`类似,是动态数组的实现。 2. `HashMap<K, V>`:等同于C#的`Dictionary...
这篇学习笔记将深入探讨Java集合框架的基础概念、主要类库以及常见应用场景。 首先,Java集合框架分为两种基本类型:List(列表)和Set(集)。List接口代表有序的集合,允许重复元素,如ArrayList和LinkedList;而...
"Java集合框架面试题" Java 集合框架是 Java 语言中的一组预定义类和接口的集合,用于存储和操作数据。下面是 Java 集合框架的知识点总结: 1. Java 集合类主要有两大分支:Collection 接口和 Map 接口。...
Java的集合框架是Java编程中不可或缺的一部分,它提供了一种高效管理对象的方式,包括存储、检索、遍历和操作对象的集合。集合框架的核心接口包括`Collection`和`List`、`Set`,它们各自有不同的特性和使用场景。 1...
### Java容器框架 Collection集合 #### 一、基本概念 Java容器类库主要目的是为了存储对象,根据不同的数据结构,可以将其划分为两个主要的概念:**Collection** ...这些知识点对于理解和应用Java集合框架至关重要。
Java集合框架是Java编程语言中一个至关重要的部分,它为数据存储和操作提供了丰富的类库。这个PPT作为培训教材,旨在深入解析Java集合框架的核心概念、接口和类,帮助学习者掌握其基本使用和高级特性。以下是Java...
在给定的文件中,我们重点关注的是Java集合框架、常用类以及String的相关知识。 首先,集合(Collections)是Java中用于存储一组对象的容器,其长度可变,允许存放不同类型的元素。集合类都位于`java.util`包下,...
本篇《The Joy of Sets》是该系列的第六部分,专注于探讨与Java集合框架中的`Set`接口相关的奇特现象。具体而言,它深入探讨了当我们在`Set`中添加和移除元素时可能遇到的问题。 #### What Does It Print? 首先,...
Java集合框架是Java编程语言中的一个核心组件,它为存储、管理和操作对象提供了一套统一的接口和类。集合框架使得开发者可以更加高效地处理数据,而无需关注底层的实现细节。本文将深入探讨Java集合框架的主要组成...
### Java集合框架和泛型机制 #### 11.1 Java集合框架概述 在Java中,集合框架(Collection Framework)是一套用于存储和操作对象集合的API。它为程序员提供了丰富的数据结构,使得数据管理更加高效和灵活。集合...