关于java里面的集合,大家经常利用到Set集合没有重复数据的特性,来进行数据的去重,那么去重的原理是怎么样的呢?

最近面试了几个人,其间有聊到集合的东西,所以就顺便问了一下这个问题,但是都是只知道这么用,

而没有去看看底层代码的去重原理(而恰恰有可能这些基础原理会被用来设计其他一些场景实现),

所以在此文章记录一下,希望能帮助到一些人:

下面是Set集合的类图:

下面我们来跟踪一下执行的过程:

1. 首先我们实例化一个set对象

Set<8大基本类型> set = new HashSet<8大基本类型>();
set.add(8大基本类型);

2.add操作会调用HashSet中的add方法,实现如下:

public boolean add(E e) {return map.put(e, PRESENT)==null;}

3.HashSet中的add方法依赖了HashMap的put方法,实现如下:

public V put(K key, V value) {if (key == null)return putForNullKey(value);int hash = hash(key.hashCode());int i = indexFor(hash, table.length);for (Entry<K,V> e = table[i]; e != null; e = e.next) {//每添加一个,则循环判断是否与map中的元素相等Object k;// 先判断hashcode是否一致,然后再判断值是否相等if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {V oldValue = e.value;e.value = value;e.recordAccess(this);return oldValue;}}modCount++;addEntry(hash, key, value, i);return null;}

很明显上述操作对8种基本类型的数据+String型是有用的,但是如果想把去重的方式应用到复杂的对象呢,上述方式就还欠缺了一点了,

知道了执行顺序和原理了的话,就知道该如何去实现了!

下面就是重写对象User的实现,重写equals和hashCode方法!

测试类:

package com.test.set;import java.util.HashSet;
import java.util.Set;public class UniqueSet {/*** * @param args*/public static void main(String[] args) {User user1 = new User(1, "a");User user2 = new User(2, "b");User user3 = new User(3, "c");User user4 = new User(2, "b");Set<User> userSet = new HashSet<User>();userSet.add(user1);userSet.add(user2);userSet.add(user3);userSet.add(user4);// 输入结果 id=1 username=a  id=2 username=b  id=3 username=c  for (User u : userSet) {System.out.println("id=" + u.id + " " + "username=" + u.username);}}
}

实现类:

package com.test.set;/*** 类描述:set集合针对String 类型和8大基础数据类型  过滤掉重复数据,* 如果存放的是其他类型对象,则需要重写hashCode方法和equals方法,* 当hashcode相等时(先执行hashCode方法),则会去执行equals方法,比较每个属性的值* 如果一致的话,则不会存进set,否则加入set集合 * */
public class User {// idprotected Integer id;// 名称protected String  username;//构造方法public User(Integer id, String username) {this.id = id;this.username = username;}/** * 如果对象类型是User,先比较hashcode,一致的场合再比较每个属性的值*/@Overridepublic boolean equals(Object obj) {if (obj == null)return false;if (this == obj)return true;if (obj instanceof User) {User user = (User) obj;// if(user.id = this.id) return true; // 只比较id  // 比较每个属性的值 一致时才返回true if (user.id == this.id && user.username.equals(this.username))return true;}return false;}/** * 重写hashcode 方法,返回的hashCode不一样才再去比较每个属性的值*/@Overridepublic int hashCode() {// return id.hashCode();return id.hashCode() * username.hashCode();}
}

以上---------------------

Java Set集合去重机制相关推荐

  1. JAVA中集合去重的三种基本方式

    在学习JAVA的过程中,总是会碰见对集合中的元素进行去重的要求,在这里总结了三种基本的去重方法. 主要的思想就是:先取元素,后进行比较,最后放回去. 案例如下: package eliminate_d ...

  2. java List集合去重保持原顺序

    LinkedHashSet去重,去重后保持原有顺序(重复数据只保留一条) String[] arr = new String[] { "a", "c", &qu ...

  3. Python--几种set集合去重的方法

    1.set集合的去重机制 ps: set集合在内部执行时,首先会先对对象执行hash算法,存储到内存空间, (但在同一次运行过程中两个值相等的对象hash值一样)所以如果两个对象值相等,这时会做出第二 ...

  4. Java List去重 Lis集合去重 List去重效率对比 List去重复元素效率对比 List去重效率

    Java  List去重 Lis集合去重 List去重效率对比 List去重复元素效率对比 List去重效率 --- List 去重复元素的几种办法 一.概述 面试的时候,有个常见的问题:" ...

  5. java中给对象的List集合去重的几种方法(Lambda)

    java中给对象的List集合去重的几种方法 前言 一.lambda表达式的去重方式 二.Stream API中的collect去重方法 三.Stream API 中的distinct方法去重 前言 ...

  6. Java List<T>去重方法,引用类型集合去重

    前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家.点击跳转到教程. 一.实体类中要重写比较方法equals,最好也重写hashcode方法 public class W ...

  7. 【Java】List集合去重的方式

    List集合去重的方式 方式一:利用TreeSet集合特性排序+去重(有序) 方式二:利用HashSet的特性去重(无序) 方式三:利用LinkedHashSet去重(有序) 方式四:迭代器去重(无序 ...

  8. java 数组合并 去重_Java集合与数组去重

    集合去重 方法一:利用集合的contains方法,创建临时集合组装数据去重 public void listTest1(){ System.out.println("方法一"); ...

  9. Java的List去重

    Java的List去重 1.contains()去重 ArrayList 的 contains() 方法的时间复杂度是O(n)O(n)O(n)的. 使用contains 进行判断去重的 时间复杂度是O ...

最新文章

  1. 展望2018:WebRTC大规模商用元年
  2. 【转】 浏览器分析模拟登陆过程
  3. 5G 标准 — R18
  4. linux-进程切换,用户态进程,内核态进程
  5. PyTorch随笔-0
  6. Text store debug FM CRM_TEXT_MAINTAIN_OW
  7. AliOS Things图形界面开发指南
  8. 备案php代码,备案查询API PHP代码
  9. 音频录制和Speech语音识别(ios10)
  10. pythonATM,购物车项目实战5-数据处理层
  11. 转行学IT为什么一定要趁早?
  12. html修改字体宋体,html怎么设置宋体
  13. chua系统matlab代码
  14. 西安联通光猫修改为桥接模式
  15. python爬取图片失败显示404_django使用图片延时加载引起后台404错误
  16. 推荐系统 -- NFM
  17. 企业文化如何推动绩效?
  18. 如何解锁CourseHero文档
  19. js超酷消息警告框美化插件
  20. 成都大学计算机图形学期末考试题,计算机图形学期末考试题

热门文章

  1. Cisco路由器IOS升级方法总结
  2. yapi自动化接口操作
  3. (笔记)关于spit截取表单提交数据区分符号中英文及正则判断
  4. [翻译]在 Jelly Bean 中使用应用加密
  5. java中存在 i+1 小于 i 的情况吗?
  6. 用Java实现周易算卦
  7. 浏览器常见的4个安全风险你中招了吗?安全浏览网页的方法
  8. 剑英陪你玩转图形学 (三)归去来
  9. 做玫瑰花的方法 用纸_史上最简单的纸玫瑰花的折法教程教你用纸编法做玫瑰花...
  10. arcgis中欧氏距离操作_ArcGIS教程:欧氏距离 (空间分析)