• 什么是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. ffmpeg错误码

    以下ffmpeg错误代码及翻译是本人遇到或发现后整理出来的,不保证包含全部错误代码 EPERM(不允许操作,无相应权限) = -1 ENOENT(文件或目录不存在) = -2 ESRCH(线程不存在) ...

  2. centos7中/tmp文件保存天数

    不要在/tmp目录下保存文件,该目录会定期清理文件 /tmp默认保存10天 /var/tmp默认保存30天 配置文件:/usr/lib/tmpfiles.d/tmp.conf 默认配置文件:# Thi ...

  3. laravel项目使用appnode部署linux系统到阿里云服务器流程记录(待补充)

    使用 SSH 连接工具,如 PuTTY.XShell.SecureCRT 等,连接 Linux 服务器后(阿里云服务器命令行内直接输入appnode安装命令,版本:mysql选5.7.php选7.2) ...

  4. 完成代码将x插入到该顺序有序线性表中,要求该线性表依然有序

    #include <stdio.h> #include <malloc.h> int main(void) { int i, n; double s = 1.3; double ...

  5. 我的第一个python web开发框架(29)——定制ORM(五)

    接下来我们要封装的是修改记录模块. 先上产品信息编辑接口代码 @put('/api/product/<id:int>/') def callback(id): ""&q ...

  6. git如何设置ssh密钥

    git设置ssh密钥 目前git支持https和git两种传输协议,github分享链接时会有两种协议可选: 1.Clone with SSH 2.Clone with HTTPS git在使用htt ...

  7. 通过ip查询自己电脑的共享文件夹

    查看电脑所有的共享文件或文件夹的三种方法如下: 方法一. 右键点击网上邻居,点击属性进入网上邻居属性页面. 选中本地连接,在窗口的左下方有详细信息,可以看到内网IP,记住IP地址. 直接在地址栏输入记 ...

  8. C# 里面swith的或者

    using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threa ...

  9. laravel学习笔记二

    代码编写提示工具

  10. 好程序员分享居中一个float元素

    好程序员分享居中一个float元素,我们布局的时候,用margin来设置float元素的外边距来达到效果.对于,在文档流中的元素,我们很容易让它水平居中,只要给元素设置一个固定的宽度,用margin: ...