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
集合 学习集合的目标: 会使用集合存储数据 会遍历集合,把数据取出来 掌握每种集合的特性 集合和数组的区别 数组的长度是固定的.集合的长度是可变的. 数组中存储的是同一类型的元素,可以存储基本数据类型 ...
随机推荐
- Django异步任务线程池
当数据库数据量很大时(百万级),许多批量数据修改请求的响应会非常慢,一些不需要即时响应的任务可以放到后台的异步线程中完成,发起异步任务的请求就可以立即响应 选择用线程池的原因是:线程比进程更为可控.不 ...
- Spring、SpringMVC、SpringBoot、SpringCloud的区别与联系
前言 Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器框架.Spring使你能够编写更干净.更可管理.并且更易于测试的代码. Spring MVC是Spring的一个模块,一个w ...
- Runtime - 关联对象使用方法及注意点
大家都知道在分类里,可以间接的添加属性,运用runtime关联对象. 如下图,只是声明了btnClickedCount的set, get方法而已 并没有生成_btnClickedCount 成员变量, ...
- CCF-CSP题解 201712-3 Crontab
做完一定要仔仔细细地看一遍题目再交,之后发现坑点只能追悔莫及.比如这次"英文缩写(不区分大小写)"\(OwQ\). 给定多个周期性执行的任务,每个任务调度执行有时间的要求.求给定时 ...
- SpringCloud分布式配置中心
一.什么是配置中心 在分布式系统中,由于服务数量巨多,为了方便服务配置文件统一管理,实时更新,所以需要分布式配置中心组件.在Spring Cloud中,有分布式配置中心组件spring cloud c ...
- Python面向对象-类、实例的绑定属性、绑定方法和__slots__
绑定属性 从之前的文章中,我们知道python是动态语言——实例可以绑定任意属性. 那如果实例绑定的属性和类的属性名一样的话,会是什么情况呢? >>> class Student(o ...
- 详解串行通信协议及其FPGA实现
前言 好久没更新博客了,这篇文章写写停停,用了近一周的时间,终于写完了.本篇文章介绍,串口协议数据帧格式.串行通信的工作方式.电平标准.编码方式及Verilog实现串口发送一个字节数据和接收一个字节数 ...
- 使用函数计算三步实现深度学习 AI 推理在线服务
目前深度学习应用广发, 其中 AI 推理的在线服务是其中一个重要的可落地的应用场景.本文将为大家介绍使用函数计算部署深度学习 AI 推理的最佳实践, 其中包括使用 FUN 工具一键部署安装第三方依赖 ...
- List<string>和string[]数组之间的相互转换,需要的朋友可以参考下
1,从System.String[]转到List<System.String> System.String[] str={"str","string" ...
- WPF之实现控件内容拖动
以下分别记录label.listbox.treeview三个控件的拖动示例: 1.对被拖动控件,实现拖动事件,主要是通过各种鼠标事件,实现DragDrop.DoDragDrop方法. 2.对于需要拖动 ...