HashMap初认识
什么是HashSet?
- 它实现了Set接口,HashSet是Set集合的子类
- 有哈希表支持的,元素不可重复的哈希码值(实际上是一个HashMap的实例).
- 它不保证set的迭代顺序(遍历元素的顺序),遍历元素的顺序和存储元素的顺序不一致.
- 允许使用null元素.HashSet,范型的确定类型必须是引用数据类型,引用数据类型的默认初值就是null
总结:无序,可为null,不可重复(由哈希码表支持),实质是一个hashMap
public static void main( String[] args )
{
//需求1:arrayList中有存放学生类,有学生张三\张三\李四,去重张三
//创建另一个集合,通过对比实体,来去重
List<Student> oldStu = new ArrayList<>();
oldStu.add(new Student(1,"张三"));
oldStu.add(new Student(1,"张三"));
oldStu.add(new Student(2,"李四"));
List<Student> newStu = new ArrayList<>();
oldStu.forEach((stu) -> {
if (!newStu.contains(stu)){
newStu.add(stu);
}
});
System.out.println(newStu);
/**
* 打印结果:[Student{id=1, name='张三'}, Student{id=1, name='张三'}, Student{id=2, name='李四'}]
* 没有去重,原因:contains比较的是实体的equals方法 ----> if (o.equals(elementData[i])),同时对象类型是Object类型,
* 所以比较的是对象的hashcode值.而每一次new 对象都会生成一个新的hash地址值,所以无法判断实体的内容是否相等.
*
* //contains
* public boolean contains(Object o) {
* return indexOf(o) >= 0;
* }
*
* //indexOf
* public int indexOf(Object o) {
* if (o == null) {
* for (int i = 0; i < size; i++)
* if (elementData[i]==null)
* return i;
* } else {
* for (int i = 0; i < size; i++)
* if (o.equals(elementData[i]))
* return i;
* }
* return -1;
* }
*/
//需求2:HashSet中有存放学生类,有学生张三\张三\李四,去重张三
Set<Person> personSet = new HashSet<>();
personSet.add(new Person(1,"张三"));
personSet.add(new Person(1,"张三"));
personSet.add(new Person(2,"李四"));
System.out.println(personSet);
/**
* 1.打印结果:[Person{id=1, name='张三'}, Person{id=2, name='李四'}, Person{id=1, name='张三'}]
* 没有去重,原因还是因为对象的hashCode()方法,因为在存放的时候,同样是存放的范型对象,每一个对象的创建都会
* 在堆中申请新的内存空间,也就是默认调用了一次hashCode(),所以第一次add和第二次add,存放的本身就是不同的,所以没有去重.
* 如何实现呢?
* 同样的重写对象的hashCode()方法和equals()方法,以保证实体的去重
* 2.打印结果:[Person{id=2, name='李四'}, Person{id=1, name='张三'}]
*
* public boolean add(E e) {
* return map.put(e, PRESENT)==null;
* }
*/
}
class Person{
private Integer id;
private String name;
public Person() {
}
public Person(Integer id, String name) {
this.id = id;
this.name = name;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Person{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Person)) return false;
Person person = (Person) o;
return Objects.equals(id, person.id) &&
Objects.equals(name, person.name);
}
@Override
public int hashCode() {
return Objects.hash(id, name);
}
}
class Student{
private Integer id;
private String name;
public Student() {
}
public Student(Integer id, String name) {
this.id = id;
this.name = name;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
@Override
public String toString() {
return "Student{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
//改进:重写equals方法,比较实体的内容
//打印结果:[Student{id=1, name='张三'}, Student{id=2, name='李四'}]
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Student)) return false;
Student student = (Student) o;
return Objects.equals(id, student.id) &&
Objects.equals(name, student.name);
}
@Override
public int hashCode() {
return Objects.hash(id, name);
}
}
HashMap初认识的更多相关文章
- Java中HashSet,HashMap和HashTable的区别
HashMap.HashSet.HashTable之间的区别是Java程序员的一个常见面试题目,在此仅以此博客记录,并深入源代码进行分析: 在分析之前,先将其区别列于下面 1:HashSet底层采用的 ...
- [置顶] HashMap HashTable HashSet区别剖析
HashMap.HashSet.HashTable之间的区别是Java程序员的一个常见面试题目,在此仅以此博客记录,并深入源代码进行分析: 在分析之前,先将其区别列于下面 1:HashSet底层采用的 ...
- 初建FreeMarker工程
初建FreeMarker工程 ——@梁WP 背景:听说freemarker可以用来写页面的组件,热衷于编写可重用代码的我,迫不及待地研究了freemarker,不过,在写组件之前,还是先研究一下fre ...
- HashMap HashTable HashSet区别剖析
HashMap.HashSet.HashTable之间的区别是Java程序员的一个常见面试题目,在此仅以此博客记录,并深入源代码进行分析: 在分析之前,先将其区别列于下面 1:HashSet底层采用的 ...
- HashMap为什么线程不安全(hash碰撞与扩容导致)
一直以来都知道HashMap是线程不安全的,但是到底为什么线程不安全,在多线程操作情况下什么时候线程不安全? 让我们先来了解一下HashMap的底层存储结构,HashMap底层是一个Entry数组,一 ...
- HashMap 源码详细分析(JDK1.8)
一.概述 本篇文章我们来聊聊大家日常开发中常用的一个集合类 - HashMap.HashMap 最早出现在 JDK 1.2中,底层基于散列算法实现.HashMap 允许 null 键和 null 值, ...
- HashTable & HashMap & ConcurrentHashMap 原理与区别
一.三者的区别 HashTable HashMap ConcurrentHashMap 底层数据结构 数组+链表 数组+链表 数组+链表 key可为空 否 是 否 value可为空 否 是 否 ...
- 六.HashMap HashTable HashSet区别剖析总结
HashMap.HashSet.HashTable之间的区别是Java程序员的一个常见面试题目,在此仅以此博客记录,并深入源代码进行分析: 在分析之前,先将其区别列于下面: 1.HashSet底层采用 ...
- 【不做标题党,只做纯干货】HashMap在jdk1.7和1.8中的实现
同步首发:http://www.yuanrengu.com/index.php/20181106.html Java集合类的源码是深入学习Java非常好的素材,源码里很多优雅的写法和思路,会让人叹为 ...
随机推荐
- DevOps 工程师实际上是做什么的
DevOps 工程师实际上是做什么的? 我们之前已经讨论过许多关于DevOps和DevOps世界的最新趋势了.但是DevOps工程师到底是做什么的? DevOps工程师以最纯粹的方式弥合了软件开发和运 ...
- 优秀代码摘录片段一:LinkedList中定位index时使用折半思想
在LinkedList有一段小代码,实现的功能是,在链表中间进行插如,所以在插如的过程中会需要找到对应的index位置的node元素: 如果放在平时只为了实现功能而进行遍历查找,很多人会直接使用一个w ...
- Android为TV端助力 eclipse build project 出现major.minor version 52.0的问题
那些网上说的JDK什么的的问题,我求你们不要误人子弟好吗? 出现在这个的原因就是ADT也就是你的SDK manager 的Tools版本跟你的SDK版本不兼容,如果你的是SDK 23.0.2那你的To ...
- vue(2)—— vue简单语法运用,常用指令集
按照前面的文章:vue(1)——node.js安装使用,利用npm安装vue 安装完vue之后,就可以使用vue了 vue vue简介 前面安装好vue之后,确实还没有对vue进行介绍,首先,官网: ...
- 20181218 - PostgreSQL Auto Commit Guide(自动提交)
20181218 - PostgreSQL Auto Commit Guide 参考官网简介,https://www.postgresql.org/docs/10/ecpg-sql-set-autoc ...
- c/c++ 多线程 std::call_once
多线程 std::call_once 转自:https://blog.csdn.net/hengyunabc/article/details/33031465 std::call_once的特点:即使 ...
- springboot运行时该注意的地方
1.SpringBoot的入口类一定要放在所有类的上一层,也就是要包含所有子包中的类 springBoot在启动时才会加载所有子包中的所有组件 否则会出现启动成功但是访问不到的情况: This app ...
- python文章装饰器理解12步
1. 函数 在python中,函数通过def关键字.函数名和可选的参数列表定义.通过return关键字返回值.我们举例来说明如何定义和调用一个简单的函数: def foo(): return 1 fo ...
- 4.机器学习——统计学习三要素与最大似然估计、最大后验概率估计及L1、L2正则化
1.前言 之前我一直对于“最大似然估计”犯迷糊,今天在看了陶轻松.忆臻.nebulaf91等人的博客以及李航老师的<统计学习方法>后,豁然开朗,于是在此记下一些心得体会. “最大似然估计” ...
- day 13 迭代器、可迭代对象、迭代器对象、生成器、生成器对象、枚举对象
迭代器大概念 # 迭代器:循环反馈的容器(集合类型)# -- 不同于索引取值,但也可以循环的从容器对象中从前往后逐个返回内部的值# 优点:不依赖索引,完成取值# 缺点:不能计算长度,不能指定位取值( ...