set集合HashSet
一:
和List接口同一级的还有Set接口,Set类型的集合,元素不能重复,存储顺序和迭代顺序没有必然联系。他的元素的唯一性是由hasCode和equals决定的。
他的子类,常用的HashSet和LinkedHashSet。
package test11; import java.util.HashSet;
import java.util.Iterator;
import java.util.Set; public class Hash_Demo {
public static void main(String[] args){
has_Test();
}
public static void has_Test(){
Set<String> set_str=new HashSet<>();
set_str.add("i");
set_str.add("j");
set_str.add("k");
set_str.add("k");
set_str.add("m");
Iterator<String> set_it=set_str.iterator();
while (set_it.hasNext()){
System.out.print(set_it.next());
}
}
}
对于我们常用的javaAPI (String、Ineteger等)的equals和hascode方法已经重写。
HashSet集合存储数据的结构:
首先我们了解什么是哈希表?
哈希表底层使用的也是数组机制,数组中也存放对象,而这些对象往数组中存放时的位置比较特殊,当需要把这些对象给数组中存放的时候,那么根据这些对象的特有的数据结合相应的算法,计算出这个对象在数据中的位置,然后把这个对象存放在数组中而这样的数组叫做哈希数组,也就是哈希表。
当向哈希表中存放元素时,需要根据元素的特有的数据结合相应的算法,这个算法其实就是Object中的hasCode方法,由于任何对象都是Object的子类,所有任何对象都有hasCode方法,算出对象的在表中的存放位置。这里需要注意,如果两个对象的hasCode方法算出的结果一样,这样叫做哈希冲突,这个时候调用对象的equals方法,比较这两个对象是不是同一个对象,如果equals方法返回true的话,就不会把第二个对象存入哈希表中。如果返回的false的时候,就会把这个值存放在hash表中。
这也就是保证了HashSet集合的元素的唯一性,其实就是根据对象的hascode和equals方法决定的。如果我们往集合存储自定义对象的话,需要我们重写hashcode和equals方法,来适用当前对象比较方法。
对于javaAPI上面代码。
对于自定义类型,需要重写hascode和equals方法。
package Id_Has; import java.util.HashSet;
import java.util.Iterator; public class Id_Set {
public static void main(String[] args){
HashSet<Person_Info> per_set=new HashSet<>();
per_set.add(new Person_Info("tom",));
per_set.add(new Person_Info("tom",));
Iterator<Person_Info> per_it=per_set.iterator();
while (per_it.hasNext())
{
System.out.print(per_it.next());
}
} } class Person_Info{
private String name;
private int age;
public Person_Info(String name,int age){
this.name=name;
this.age=age;
} public String getName() {
return name;
}
public int getAge(){
return age;
}
public boolean equals(Object obj){
if(obj==null){
return false;
}
if(obj==this){
return true;
}
if(obj instanceof Person_Info){
Person_Info new_obj=(Person_Info)obj;
if(new_obj.name.equals(this.name)&& new_obj.age==this.age){
return true;
}
}
return false;
}
public int hashCode(){
final int prime=;
int result=;
result=result*prime+age;
result=prime * result + ((name == null) ? : name.hashCode());
return result;
}
public String toString(){
return "Person_Info[" +this.name+" "+this.age + "]";
}
}
我们需要对equals方法进行重写以及hashCode方法。
equals方法:
public boolean equals(Object obj){
if(obj==null){
return false;
}
if(obj==this){
return true;
}
if(obj instanceof Person_Info){
Person_Info new_obj=(Person_Info)obj;
if(new_obj.name.equals(this.name)&& new_obj.age==this.age){
return true;
}
}
return false;
}
hashCode方法:
public int hashCode(){
final int prime=;
int result=;
result=result*prime+age;
result=prime * result + ((name == null) ? : name.hashCode());
return result;
}
其中hashCode方法的重写,是参考JavaApi进行重写。
字符串的hashCode的重写,其中private int hash; // Default to 0 然后用h的值乘以31在和字符对应的数值进行计算得到一个整数作为字符串的hashCode。因为字符串这种保证了hashCode唯一性。然后我们重写的时候
其中有个值是唯一的就是name的hashCode。
总结如下:
hashCode相等的,不一定对象相等。
对象相等,hashCode相等,
HashSet的是无序的,存储和遍历,但是如果我们想要存取顺序的怎么办呢?
HashSet的子类有个子类:LinkedHashset。
public class LinkedHashSet<E> extends HashSet<E> implements Set<E>, Cloneable, Serializable
他是链表和Hashset的结合。
code:
package test11; import java.util.Iterator;
import java.util.LinkedHashSet; public class LinkHash_Demo {
public static void main(String[] args){
linkHashTest(); }
public static void linkHashTest(){
LinkedHashSet<String> link=new LinkedHashSet<>();
link.add("e");
link.add("f");
link.add("g");
link.add("i");
Iterator<String> linkit=link.iterator();
while (linkit.hasNext()){
System.out.print(linkit.next());
}
}
}
输出结果:
二:ArrayList中的判断元素是否重复原理:
非自定义类型,ArrayList在判断一个元素是否包含这个元素,使用的是contains()方法来判断,实际上使用的equals方法来进行判断,非自定义类型的数据类型equals方法都进行重写,自定义类型的数据需要自己重写的方法,
否则判断的是对象的内存地址是否相等。有时候我们判断一个对象是否相等,是通过对象的属性进行判断而不是单单内存地址,内存地址相等一定是同一个对象,但是对象的内存地址不相等并不能说明两个对象不相等。
最终通过equals来遍历数组判断是否有相等元素。
三:Hashset的add方法和contians方法
因为set集合是无序、唯一的。那set如何判断一个元素是否重复呢?
通过hashCode 和equals方法进行判断。首先计算出要添加元素的hashcode 然后跟集合里的元素的hashcode进行判断,如果不相等,则插入元素,如果相等的话,在和集合的元素进行equals方法的比较,返回true
则不添加元素,如果返回false的话,添加元素。
在对自定义类型的进行set操作的时候,需要重写equals和hashCode方法的重写。
总结:
List与Set集合的区别?
List:
它是一个有序的集合(元素存与取的顺序相同)
它可以存储重复的元素
Set:
它是一个无序的集合(元素存与取的顺序可能不同)
它不能存储重复的元素
List集合中的特有方法
void add(int index, Object element) 将指定的元素,添加到该集合中的指定位置上
Object get(int index)返回集合中指定位置的元素。
Object remove(int index) 移除列表中指定位置的元素, 返回的是被移除的元素
Object set(int index, Object element)用指定元素替换集合中指定位置的元素,返回值的更新前的元素
ArrayList:
底层数据结构是数组,查询快,增删慢
LinkedList:
底层数据结构是链表,查询慢,增删快
HashSet:
元素唯一,不能重复
底层结构是 哈希表结构
元素的存与取的顺序不能保证一致
如何保证元素的唯一的?
重写hashCode() 与 equals()方法
LinkedHashSet:
元素唯一不能重复
底层结构是 哈希表结构 + 链表结构
元素的存与取的顺序一致
set集合HashSet的更多相关文章
- Java集合 -- HashSet 和 HashMap
HashSet 集合 HashMap 集合 HashSet集合 1.1 Set 接口的特点 Set体系的集合: A:存入集合的顺序和取出集合的顺序不一致 B:没有索引 C:存入集合的元素没有重复 1. ...
- java集合-HashSet
HashSet 概述 对于 HashSet 而言,它是基于 HashMap 实现的,底层采用 HashMap 来保存元素,所以如果对 HashMap 比较熟悉了,那么学习 HashSet 也是很轻松的 ...
- Java 集合 - HashSet
一.源码解析 public class HashSet<E> extends AbstractSet<E> implements Set<E>, Cloneable ...
- Java集合---HashSet的源码分析
一. HashSet概述: HashSet实现Set接口,由哈希表(实际上是一个HashMap实例)支持.它不保证set 的迭代顺序:特别是它不保证该顺序恒久不变.此类允许使用null元素. 二. ...
- Set集合——HashSet、TreeSet、LinkedHashSet(2015年07月06日)
一.Set集合不同于List的是: Set不允许重复 Set是无序集合 Set没有下标索引,所以对Set的遍历要通过迭代器Iterator 二.HashSet 1.HashSet由一个哈希表支持,内部 ...
- 哈希集合——hashSet
/** 哈希集合特点:存取顺序不确定,同一个哈希值的位置可以存放多个元素, 哈希集合存放元素的时候是先判断哈希地址值:hashCode()是否相同,如果不同 ...
- ava集合---HashSet的源码分析
一.HasnSet概述 Hashset实现set接口,由哈希表(实际上是一个HashMap实例)支持.它不保证set的迭代顺序.特别是它不保证该顺序恒久不变.此类允许使用Null元素 一.HasnSe ...
- java集合-HashSet源码解析
HashSet 无序集合类 实现了Set接口 内部通过HashMap实现 // HashSet public class HashSet<E> extends AbstractSet< ...
- 集合-HashSet
参考博客:https://www.cnblogs.com/runwulingsheng/p/5208762.html https://www.cnblogs.com/ysocean/p/6555373 ...
- 基于散列的集合 HashSet\HashMap\HashTable
HashSet\HashMap\HashTable 1 基于散列的集合 2 元素会根据hashcode散列,因此,集合中元素的顺序不一定与插入的顺序一致. 3 根据equals方法与hashCode方 ...
随机推荐
- 使用JSON实现分页
使用JSON实现分页可直接用 Fenye.html <!DOCTYPE html> <html> <head> <title>JSON分页</ti ...
- 【代码笔记】iOS-iphone开发之获取系统字体
代码: - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view. NS ...
- 仿饿了吗点餐界面两个ListView联动效果
这篇文章主要介绍了仿饿了点餐界面2个ListView联动效果的相关资料,非常不错,具有参考借鉴价值,需要的朋友可以参考下 如图是效果图: 是仿饿了的点餐界面 1.点击左侧的ListView,通过在在适 ...
- 在weblogic下部署找不到授权文件的解决方法
很多用户在weblogic上部署的时候,会遇到类似的报错信息,提示授权找不到,解决这个问题的思路如下: 第一步确定授权的没有过期, 客户如果修改了系统时间,会对授权生效产生影响,在进行操作前先将 ...
- UltraPtr下拉刷新
github: https://github.com/liaohuqiu/android-Ultra-Pull-To-Refresh <in.srain.cube.views.ptr.PtrF ...
- 在Windows Server 2012中打开传统的磁盘管理界面
在“运行”中输入diskmgmt.msc即可
- zabbix系列之三——安装报错
1Zabbix_server启动失败 1.1查看日志:vi /var/log/zabbix/zabbix_server.log zabbix_server [23500]: cannot open l ...
- Jquery Ajax 提交json数据
在MVC控制器(这里是TestController)下有一个CreateOrder的Action方法 [HttpPost] public ActionResult CreateOrder(List&l ...
- 关于Entity Framework关系配置,提示列名XXXX_Id无效的问题
问题描述 : 数据库中有两张表,如下: Member(会员)表有外键RoleId,对应的是Role(角色)表的主键Id,业务逻辑是Member表的RoleId必须与Role表的Id对应(但在设计数据表 ...
- October 09th 2017 Week 41st Monday
My motto is: Contended with little, yet wishing for more. 我的座右铭是:为一点点感到满足,但希望获得更多. If you can live y ...