java之Set接口(单列集合)
Set接口概述
- java.util.Set接口 extends Collection接口
- 不允许存储重复的元素
- 没有索引,没有带索引的方法,也不能使用普通的for循环遍历
HashSet集合介绍
- java.util.HashSet集合 implements Set接口
- 不允许存储重复的元素
- 没有索引,没有带索引的方法,也不能使用普通的for循环遍历
- 是一个无序的集合,存储元素和取出元素的顺序有可能不一致
- 底层是一个哈希表结构(查询的速度非常的快)
HashSet集合存储数据的结构(哈希表)
什么是哈希值?
- 哈希值:是一个十进制的整数,由系统随机给出(就是对象的地址值,是一个逻辑地址,是模拟出来得到地址,不是数据实际存储的物理地址)。
- 在JDK1.8之前,哈希表底层采用数组+链表实现,即使用链表处理冲突,同一hash值的链表都存储在一个链表里。 但是当位于一个桶中的元素较多,即hash值相等的元素较多时,通过key值依次查找的效率较低。而JDK1.8中,哈 希表存储采用数组+链表+红黑树实现,当链表长度超过阈值(8)时,将链表转换为红黑树,这样大大减少了查找 时间。 简单的来说,哈希表是由数组+链表+红黑树(JDK1.8增加了红黑树部分)实现的。总而言之,JDK1.8引入红黑树大程度优化了HashMap的性能,那么对于我们来讲保证HashSet集合元素的唯一,其实就是根据对象的hashCode和equals方法来决定的。如果我们往集合中存放自定义的对象,那么保证其唯一,就必须复写hashCode和equals方法建立属于当前对象的比较方式。
如何保证Set集合中的存储的数据唯一性
如果我们往集合中存放自定义的对象,那么保证其唯一, 就必须复写hashCode和equals方法建立属于当前对象的比较方式。
详解Set存储元素原理:
当我们使用Set集合中的add方法往集合中添加元素的时候:
- add方法就会调用要添加的元素的hashCode方法,计算要添加元素的哈希值。
- 然后add方法在集合中去寻找有没有要添加元素的哈希值,如果没有则添加到集合中去。
- 如果发现有(哈希冲突),则要添加的元素会调用equals方法和哈希值相同的元素进行比较,如果返回true。则认定2个元素为同一个,不会在添加到Set集合中去了。如果equals方法返回结果为false,则添加到集合中去。
代码举例
要求: 同名同年龄的人,视为同一个人,只能存储一次
定义Person类
package demo02HashSet;
import java.util.Objects;
public class Person {
private String name;
private int age;
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
//重写equals方法
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Person person = (Person) o;
return age == person.age &&
Objects.equals(name, person.name);
}
//重写hashCode
@Override
public int hashCode() {
return Objects.hash(name, age);
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", 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;
}
}
定义hashSet集合存储Person类
package demo02HashSet;
import java.util.HashSet;
public class Demo01HashSetPersonTest {
public static void main(String[] args) {
//创建HashSet集合存储Person
HashSet<Person> set = new HashSet<>();
Person p1 = new Person("小美女", 18);
Person p2 = new Person("小美女", 18);
Person p3 = new Person("小美女", 19);
//查看哈希值
System.out.println(p1.hashCode());
System.out.println(p2.hashCode());
System.out.println(p1.equals(p2));//true
set.add(p1);
set.add(p2);
set.add(p3);
//查看集合里的元素
System.out.println(set);//[Person{name='小美女', age=19}, Person{name='小美女', age=18}]
}
}
LinkedHashSet类
可变参数简介
可变参数:JDK1.5之后出现的新特性。如果我们定义一个方法需要接受多个参数,并且多个参数类型一致,我们可以使用可变参数。
使用前提:
- 当方法的参数列表数据类型已经确定,但是参数的个数不确定,就可以使用可变参数.
使用格式:
修饰符 返回值类型 方法名(参数类型... 形参名){
方法体
}
其实这个书写完全等价于
修饰符 返回值类型 方法名(参数类型[] 形参名){
方法体
}
可变参数的原理:
- 可变参数底层就是一个数组,根据传递参数个数不同,会创建不同长度的数组,来存储这些参数。传递的参数个数,可以是0个(不传递),1,2...多个
可变参数的注意事项
- 一个方法的参数列表,只能有一个可变参数
- 如果方法的参数有多个,那么可变参数必须写在参数列表的末尾
package demo02HashSet;
public class ChangeArgs {
public static void main(String[] args) {
int[] arr = {1, 4, 62, 431, 2};
int sum = getSum(arr);
System.out.println(sum);//500
// 求 这几个元素和 6 7 2 12 2121
int sum2 = getSum(6, 7, 2, 12, 2121);
System.out.println(sum2);
}
/*
* 完成数组 所有元素的求和 原始写法
public static int getSum(int[] arr){
int sum = 0;
for(int a : arr){
sum += a;
}
return sum;
}
*/
//可变参数写法
public static int getSum(int... arr) {
int sum = 0;
for (int a : arr) {
sum += a;
}
return sum;
}
//可变参数的特殊(终极)写法
public static void method(Object... obj) {
}
}
java之Set接口(单列集合)的更多相关文章
- java内部类、接口、集合框架、泛型、工具类、实现类
.t1 { background-color: #ff8080; width: 1100px; height: 40px } 一.内部类 1.成员内部类. (1)成员内部类的实例化: 外部类名.内部类 ...
- java 单列集合总结
Collection 接口 add() remove() contains() clear(); size(); 迭代器遍历(普通迭代器,不能再遍历过程中修改集合的长度) List接口 单列集合 有序 ...
- java之List接口(单列集合)
List接口概述 查询API我们可知:java.util.List 接口继承自 Collection 接口,是单列集合的一个重要分支,习惯性地会将实现了 List 接口的对 象称为List集合.在Li ...
- Java之Iterator接口(遍历单列集合的迭代器)
Iterator接口概述 在程序开发中,经常需要遍历集合中的所有元素.针对这种需求,JDK专门提供了一个接口java.util.Iterator . Iterator 接口也是Java集合中的一员,但 ...
- Java之Collection接口(单列集合根接口)
集合概述 集合到底是什么呢?集合:集合是java中提供的一种容器,可以用来存储多个数据 集合和数组既然都是容器,它们有啥区别呢? 区别1: 数组的长度是固定的. 集合的长度是可变的. 区别2: 数组 ...
- Java中的集合(二)单列集合顶层接口------Collection接口
Java中的集合(二)单列集合顶层接口------Collection接口 Collection是一个高度封装的集合接口,继承自Iterable接口,它提供了所有集合要实现的默认方法.由于Iterab ...
- Java学习笔记32(集合框架六:Map接口)
Map接口与Collection不同: Collection中的集合元素是孤立的,可理解为单身,是一个一个存进去的,称为单列集合 Map中的集合元素是成对存在的,可理解为夫妻,是一对一对存进去的,称为 ...
- Java之Map接口(双列集合)
Map集合概述 现实生活中,我们常会看到这样的一种集合:IP地址与主机名,身份证号与个人,系统用户名与系统用户对象等,这种一一对应的关系,就叫做映射.Java提供了专门的集合类用来存放这种对象关系的对 ...
- Java学习:单列集合Collection
集合 学习集合的目标: 会使用集合存储数据 会遍历集合,把数据取出来 掌握每种集合的特性 集合和数组的区别 数组的长度是固定的.集合的长度是可变的. 数组中存储的是同一类型的元素,可以存储基本数据类型 ...
随机推荐
- Kubernetes 应用部署实战
Kubernetes 应用部署实战 2018-08-08 19:44:56 wuxiangping2017 阅读数 3084 收藏 更多 分类专栏: linux运维与架构师 简介 伙计们,请搬好 ...
- 一篇文章让你明白CPU缓存一致性协议MESI
CPU高速缓存(Cache Memory) CPU为何要有高速缓存 CPU在摩尔定律的指导下以每18个月翻一番的速度在发展,然而内存和硬盘的发展速度远远不及CPU.这就造成了高性能能的内存和硬盘价格及 ...
- AJAX中的dataType
参考ajax的api文档 dataType的类型:String ajax中的dataType的属性: text:返回纯文本字符串 json:返回json数据 jsonp:jsonp格式(我没用过) h ...
- LCT能干啥???
LCT能干啥 模板: 维护可加的树链信息:询问都是一条链上的信息:维护方式和线段树差不多: 增加一条边: 删除一条边: 修改一个点权: 修改一条路径上的所有点的点权: 整体来说 ...
- iis部署网站后出现未能写入输出文件“c:\Windows\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET Files\root\106f9ae8\cc0e1
在本地开发环境没问题,但是发布到服务器出现:未能写入输出文件“c:\Windows\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET Fil ...
- 《Java基础知识》一维,二维数组的申明和使用
为什么要使用数组: 因为不使用数组计算多个变量的时候太繁琐,不利于数据的处理. -------- 数组也是一个变量,是存储一组相同类型的变量 声明一个变量就是在内存中划出一块合适的空间 声明一个数 ...
- Java8 Stream —— 更丝滑的集合操作方式
一.概念 Stream是一种可供流式操作的数据视图有些类似数据库中视图的概念它不改变源数据集合如果对其进行改变的操作它会返回一个新的数据集合. 总的来讲它有三大特性:在之后我们会对照着详细说明 ...
- 小米开源数据库<pegasus>简介
数据模型 组合键:Table + HashKey + SortKey Table实现业务数据的隔离 HashKey决定数据在那个分片 SortKey决定数据在分片内的排序 一致性协议 使用Pacifi ...
- Redis-API
Redis-API 简介 Redis 是一个基于内存的高效的键值行非关系型数据库,存取效率极高. python提供了两个类:分别为Redis和StrictRedis来实现Redis的命令操作.Redi ...
- hadoop伪分布模式的配置和一些常用命令
大数据的发展历史 3V:volume.velocity.variety(结构化和非结构化数据).value(价值密度低) 大数据带来的技术挑战 存储容量不断增加 获取有价值的信息的难度:搜索.广告.推 ...