• 什么是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初认识的更多相关文章

  1. Java中HashSet,HashMap和HashTable的区别

    HashMap.HashSet.HashTable之间的区别是Java程序员的一个常见面试题目,在此仅以此博客记录,并深入源代码进行分析: 在分析之前,先将其区别列于下面 1:HashSet底层采用的 ...

  2. [置顶] HashMap HashTable HashSet区别剖析

    HashMap.HashSet.HashTable之间的区别是Java程序员的一个常见面试题目,在此仅以此博客记录,并深入源代码进行分析: 在分析之前,先将其区别列于下面 1:HashSet底层采用的 ...

  3. 初建FreeMarker工程

    初建FreeMarker工程 ——@梁WP 背景:听说freemarker可以用来写页面的组件,热衷于编写可重用代码的我,迫不及待地研究了freemarker,不过,在写组件之前,还是先研究一下fre ...

  4. HashMap HashTable HashSet区别剖析

    HashMap.HashSet.HashTable之间的区别是Java程序员的一个常见面试题目,在此仅以此博客记录,并深入源代码进行分析: 在分析之前,先将其区别列于下面 1:HashSet底层采用的 ...

  5. HashMap为什么线程不安全(hash碰撞与扩容导致)

    一直以来都知道HashMap是线程不安全的,但是到底为什么线程不安全,在多线程操作情况下什么时候线程不安全? 让我们先来了解一下HashMap的底层存储结构,HashMap底层是一个Entry数组,一 ...

  6. HashMap 源码详细分析(JDK1.8)

    一.概述 本篇文章我们来聊聊大家日常开发中常用的一个集合类 - HashMap.HashMap 最早出现在 JDK 1.2中,底层基于散列算法实现.HashMap 允许 null 键和 null 值, ...

  7. HashTable & HashMap & ConcurrentHashMap 原理与区别

    一.三者的区别     HashTable HashMap ConcurrentHashMap 底层数据结构 数组+链表 数组+链表 数组+链表 key可为空 否 是 否 value可为空 否 是 否 ...

  8. 六.HashMap HashTable HashSet区别剖析总结

    HashMap.HashSet.HashTable之间的区别是Java程序员的一个常见面试题目,在此仅以此博客记录,并深入源代码进行分析: 在分析之前,先将其区别列于下面: 1.HashSet底层采用 ...

  9. 【不做标题党,只做纯干货】HashMap在jdk1.7和1.8中的实现

     同步首发:http://www.yuanrengu.com/index.php/20181106.html Java集合类的源码是深入学习Java非常好的素材,源码里很多优雅的写法和思路,会让人叹为 ...

随机推荐

  1. 基于LBS的六边形热力图算法

    六边形算法: 我把六边形铺满的分布图进行了切分,切分为矩形,每个矩形中有一个六边形.4个三角形.两个小长方形,依次计算.边界判断上,采用主流的MP>MN的方式(M为上边界对称点,N为与六边形的交 ...

  2. 彻底删除mysql服务(清理注册表)

    由于安装某个项目的执行文件,提示要卸载MySQL以便它自身MySQL安装,然后我禁用了MYSQL服务,再把这个文件夹删除后,发现还是提示请卸载MYSQL服务. 解决步骤: 1.以管理员身份运行命令提示 ...

  3. 重置Visual Studio 2017的配置

    1,从命令行进入VS 2017安装目录下面的Common7\IDE文件夹. 例如,Windows 10系统中 VS 2017 企业版的默认安装目录如下: C:\Program Files (x86)\ ...

  4. python正则表达式相关记录

    1 python中字符串前加‘r’,即可阻止‘\’导致的字符转义.但是在re.sub()中参数中加'r'不会起作用.

  5. 目录命令(dir)

    DIR 命令: // 描述: (Directory) 显示目录的文件和子目录的列表. // 语法: dir [<Drive>:][<Path>][<FileName> ...

  6. jpa 联合查询方法

    public interface TaskBaseline { String getNumber(); String getTitle(); String getName(); String getP ...

  7. axios请求本地的json文件在打包部署到子目录域名下,路径找不到

    前言: 因为要同时部署两个项目,有一个是部署到域名下面的子目录下,如:https://xxx.com/siot-admin vue 项目中使用axios请求了本地项目的static文件夹下的json文 ...

  8. Loj #2494. 「AHOI / HNOI2018」寻宝游戏

    Loj #2494. 「AHOI / HNOI2018」寻宝游戏 题目描述 某大学每年都会有一次 Mystery Hunt 的活动,玩家需要根据设置的线索解谜,找到宝藏的位置,前一年获胜的队伍可以获得 ...

  9. 19 python初学(os 模块,sys 模块,hashlib 模块)

    os 模块: # _author: lily # _date: 2019/1/13 import os print(os.getcwd()) # 得到当前的工作目录 # print(os.chdir( ...

  10. 写个.net开发者的Linux迁移指南

    前言 为什么要迁移到Linux 首先我个人还是有点软件洁癖,以前是穷酸学生的时候也是用盗版的用户,后来在知乎被洗脑终于有了点版权意识.然后便有了能用开源软件的就用开源,实在不能就选社区版或者免费版.于 ...