Java学习笔记31(集合框架五:set接口、哈希表的介绍)
set接口的特点:
1.不包含重复元素
2.set集合没有索引,只能用迭代器或增强for循环遍历
3.set的底层是map集合
方法和Collection的方法基本一样
set接口的实现类HashSet:
1.无序集合
2.可以存入空(null)
3.不可以存在重复元素
示例:
- package demo;
- import java.util.HashSet;
- import java.util.Iterator;
- import java.util.Set;
- public class HashSetDemo {
- public static void main(String[] args) {
- Set<String> set = new HashSet<String>();
- set.add("abc1");
- set.add("abc1");
- set.add("abc2");
- set.add("abc3");
- set.add("abc4");
- Iterator<String> i1 = set.iterator();
- while(i1.hasNext()){
- System.out.println(i1.next());
- }
- }
- }
- /*
- 输出:
- 注意:这里的输出特点是无序的
- abc1
- abc4
- abc2
- abc3
- */
set底层数据结构是哈希表:
特点:存储取出都比较快
原理:具体省略,简单说就是链表数组结合体
对象的哈希值:普通的一个整数
可以理解为身份证号,是hashset存储的依据
- package demo;
- public class Person {}
- package demo;
- public class HashDemo {
- public static void main(String[] args) {
- Person p = new Person();
- int i = p.hashCode();
- System.out.println(i);
- //每次运行都会输出不同的整数,比如1191201656
- String s1 = new String("abc");
- String s2 = new String("abc");
- System.out.println(s1.hashCode());//
- System.out.println(s2.hashCode());//96354
- //这里Stirng重写hashcode方法,有对应的计算公式
- //当字符串的内容相同时候,运算结果就相同,因此s1和s2的哈希值相同
- }
- }
哈希表存储过程:
1.调用对象的哈希值
2.集合在容器内搜索有没有重复的哈希值,如果没有,存入新元素,记录哈希值
3.再次存储,重复上边的过程
4.如果有重复的哈希值,调用后来者的equals方法,参数为前来者,结果得到true,集合判断为重复元素,不存入
相同的字符串如果存进去,哈希值相同,equals方法为true,不会存入相同的
只要哈希值相同或者equals方法为true都成立才不会存入,只要其中一条不满足,都会储存
哈希表存储自定义对象:
- package demo;
- public class Person {
- private String name;
- private int 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;
- }
- public String toString() {
- return this.name + ":" + this.age;
- }
- public Person() {
- }
- public Person(String name, int age) {
- super();
- this.name = name;
- this.age = age;
- }
- }
- package demo;
- import java.util.HashSet;
- public class HashDemo {
- public static void main(String[] args) {
- HashSet<Person> setPerson = new HashSet<Person>();
- setPerson.add(new Person("a",17));
- setPerson.add(new Person("b",20));
- setPerson.add(new Person("b",20));
- setPerson.add(new Person("c",18));
- System.out.println(setPerson);
- //[c:18, b:20, a:17, b:20]
- //发现存入了重复的元素
- //所以想办法使name和age相同的Person对象视为同一个对象
- //所以需要重写hashcode方法
- }
- }
自己重写:
- package demo;
- public class Person {
- private String name;
- private int 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;
- }
- public String toString() {
- return this.name + ":" + this.age;
- }
- public Person() {
- }
- public Person(String name, int age) {
- super();
- this.name = name;
- this.age = age;
- }
- public int hashCode(){
- return name.hashCode()+age*66;
- }
- public boolean equals(Object obj) {
- if (this == obj) {
- return true;
- }
- if (obj == null) {
- return false;
- }
- if (obj instanceof Person) {
- Person p = (Person) obj;
- return name.equals(p.name) && age == p.age;
- }
- return false;
- }
- }
eclipse可以帮助我们写:
- package demo;
- public class Person {
- private String name;
- private int 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;
- }
- public String toString() {
- return this.name + ":" + this.age;
- }
- public Person() {
- }
- public Person(String name, int age) {
- super();
- this.name = name;
- this.age = age;
- }
- @Override
- public int hashCode() {
- final int prime = 31;
- int result = 1;
- result = prime * result + age;
- result = prime * result + ((name == null) ? 0 : name.hashCode());
- return result;
- }
- @Override
- public boolean equals(Object obj) {
- if (this == obj)
- return true;
- if (obj == null)
- return false;
- if (getClass() != obj.getClass())
- return false;
- Person other = (Person) obj;
- if (age != other.age)
- return false;
- if (name == null) {
- if (other.name != null)
- return false;
- } else if (!name.equals(other.name))
- return false;
- return true;
- }
- }
LinkedHashSet集合:基于链表的哈希表实现,继承HashSet,它具有顺序
示例:
- package demo;
- import java.util.LinkedHashSet;
- public class LinkedHashSetDemo {
- public static void main(String[] args) {
- //有序的set
- LinkedHashSet<Integer> link = new LinkedHashSet<Integer>();
- link.add(1);
- link.add(2);
- link.add(3);
- link.add(4);
- System.out.println(link);
- //[1, 2, 3, 4]
- }
- }
关于hashcode和equals的一些问题,在面试中会问道:
1.两个对象哈希值相同,那么equals方法一定返回true吗?不一定
取决于如何重写equals,如果重写固定了它返回false,结果就一定是false
2.equals方法返回true,那么哈希值一定相同吗?一定
如果类中定义一个静态变量(static int a = 1),然后重写hashcode返回a+1,那么每一个对象的哈希值都不一样
不过java中规定:对象相等,必须具有相同的哈希码值,所以这里是一定的
Java学习笔记31(集合框架五:set接口、哈希表的介绍)的更多相关文章
- 【Java学习笔记】<集合框架>定义功能去除ArrayList中的重复元素
import java.util.ArrayList; import java.util.Iterator; import cn.itcast.p1.bean.Person; public class ...
- 【Java学习笔记】<集合框架>对字符串进行长度排序
package 测试; import java.util.Comparator; public class ComparatorByLength implements Comparator { //定 ...
- 【Java学习笔记】<集合框架>TreeSet,Comparable,Comparator
public class Person implements Comparable{ private String name; private int age; public Person(){ su ...
- Java学习笔记之---集合
Java学习笔记之---集合 (一)集合框架的体系结构 (二)List(列表) (1)特性 1.List中的元素是有序并且可以重复的,成为序列 2.List可以精确的控制每个元素的插入位置,并且可以删 ...
- Java学习笔记31(IO:Properties类)
Properties类,表示一个持久的j集,可以存在流中,或者从流中加载 是Hashtable的子类 map集合的方法都能用 用途之一:在开发项目中,我们最后交给客户的是一个编译过的class文件,客 ...
- Java基础学习笔记十七 集合框架(三)之Map
Map接口 通过查看Map接口描述,发现Map接口下的集合与Collection接口下的集合,它们存储数据的形式不同,如下图. Collection中的集合,元素是孤立存在的(理解为单身),向集合中存 ...
- 【原】Java学习笔记026 - 集合
package cn.temptation; public class Sample01 { public static void main(String[] args) { // 需求:从三国演义中 ...
- JavaSE 学习笔记之集合框架(十八)
集合框架:,用于存储数据的容器. 特点: 1:对象封装数据,对象多了也需要存储.集合用于存储对象. 2:对象的个数确定可以使用数组,但是不确定怎么办?可以用集合.因为集合是可变长度的. 集合和数组的区 ...
- Java学习笔记之集合
集合(Collection)(掌握) (1)集合的由来? 我们学习的是Java -- 面向对象 -- 操作很多对象 -- 存储 -- 容器(数组和StringBuffer) -- 数组而数组的长度固定 ...
随机推荐
- java 集合是否有序
参考:https://www.cnblogs.com/hoobey/p/5914226.html
- .do的消除
其实就是在web.xml中去掉.do即可 那里有拦截器作用,什么样的文件可以进入前端控制器1
- mysql 按出现次数排序
SELECT * FROM table a LEFT JOIN (SELECT key,count(*) as c FROM table GROUP BY key ) b on a.key=b.k ...
- python虚拟环境的搭建
使用python虚拟环境作用是项目与项目之间相互隔离,互相不受影响,比如当需要同时部署A.B两个项目时,A项目依赖C库的1.0版本,B项目依赖C库的2.0版本,假如不使用虚拟环境隔离A项目和B项目就很 ...
- ubuntu系统安装微信小程序开发工具
在ubuntu系统中安装微信小程序开发工具之前,先要安装wine与git 一.安装wine 1.如果您的系统是64位,启用32位架构(如果您还没有) sudo dpkg --add-architect ...
- ABP框架 配置权限、本地语言文件、左侧菜单项
1.Framework.Core>Authorization>PermissionNames.cs 这里新增权限项 namespace Framework.Authorization { ...
- permissions required by Vibrator.vibrate: android.permission.VIBRATE
<!-- 静止休眠 --><uses-permission android:name="android.permission.WAKE_LOCK" />&l ...
- innobackupex 备份 Xtrabackup 增量备份
Mysql增量备份Xtrabackup中包含两个工具:• xtrabackup - 用于热备份innodb, xtradb表的工具,不能备份其他表(MYISAM表).• i ...
- 下拉列表 通过option 改变div的内容
<!DOCTYPE html><html> <head> <meta charset="UTF-8"> <title>& ...
- Java集合:HashSet的源码分析
Java集合---HashSet的源码分析 一. HashSet概述: HashSet实现Set接口,由哈希表(实际上是一个HashMap实例)支持.它不保证set 的迭代顺序:特别是它不保证该 ...