一、set接口

概念:set接口继承自Collection接口,与List接口不同的是,set接口所储存的元素是不重复的。

二、HashSet集合

概念:是set接口的实现类,由哈希表支持(实际上是一个HashMap集合)。HashSet集合元素的提取顺序与存储顺序不相同。

   采用哈希表数据结构存储数据,保证元素唯一性的方式依赖于:hashCode()与equals()方法。

2.1哈希表

  什么是哈希表? 链表与数组的组合。

  哈希表底层使用的也是数组机制,数组中也存放对象,而这些对象往数组中存放时的位置比较特殊,当需要把这些对象给数组中存放时,

那么会根据这些对象的特有数据结合相应的算法,计算出这个对象在数组中的位置,然后把这个对象存放在数组中。而这样的数组就称为哈希数组,即就是哈希表。

  当向哈希表中存放元素时,需要根据元素的特有数据结合相应的算法,这个算法其实就是Object类中的hashCode方法。由于任何对象都是Object类的子类,所以任何对象有拥有这个方法。即就是在给哈希表中存放对象时,会调用对象的hashCode方法,算出对象在表中的存放位置,这里需要注意,如果两个对象hashCode方法算出结果一样,这样现象称为哈希冲突,这时会调用对象的equals方法,比较这两个对象是不是同一个对象,如果equals方法返回的是true,那么就不会把第二个对象存放在哈希表中,如果返回的是false,就会把这个值存放在哈希表中。

  总结:保证HashSet集合元素的唯一,其实就是根据对象的hashCode和equals方法来决定的。如果我们往集合中存放自定义的对象,那么保证其唯一,就必须复写hashCode和equals方法建立属于当前对象的比较方式。

  Hashcode方法用来计算哈希值。

hashCode方法计算图:

哈希表数组和链表的结合图:

2.2HashSet存储JavaAPI中的类型元素

给HashSet中存储JavaAPI中提供的类型元素时,不需要重写元素的hashCode和equals方法,因为这两个方法,在JavaAPI的每个类中已经重写完毕,如String类、Integer类等。

练习实例:

1.向哈希表添加元素并且打印

import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet; public class Demo01 {
//哈希表
public static void main(String[] args) {
// TODO Auto-generated method stub
method1();
     method2();
     method3();
     method4();
}
public static void method1(){
HashSet<String> set=new HashSet<String> ();
set.add("abc");
set.add("abc");
set.add("ghi");
System.out.println(set); //
}

打印结果:因为唯一性,所以只存储了一个“abc”.

2.打印哈希值

//hashcode 方法(object类中提供)
public static void method2(){
String s1=new String("abc");
String s2=new String("abc");
//运行出来的 叫哈希值 运行的hashcode是string类的
System.out.println(s1.hashCode());
System.out.println(s2.hashCode());
}

打印结果:哈希值  hashCode()

3.向哈希表中添加自定义类的元素并打印

自定义Person类:

public class Person {
private String name;
private int age;
public Person(){ }
//重载构造方法,创建时赋值
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
} @Override
//转为字符串
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
//重写hashCode()方法
public int hashCode() { return name.hashCode()+age*31;
}
@Override
//重写equals()方法
public boolean equals(Object obj) {
if(this==obj){
return true;
}
if(obj==null){
return false;
}
if(obj instanceof Person){
Person p=(Person) obj;
return name.equals(p.name)&&age==p.age;
}
return false;
}
}

测试类方法:

public static void method3(){
HashSet<Person> set=new HashSet<Person>();
set.add(new Person("a",20));
set.add(new Person("a",10));
set.add(new Person("b",30));
set.add(new Person("b",30));
System.out.println(set);
}

运行结果:因为重写了hashCode方法跟equals方法  所以重复的元素并没有存储到集合中

三、LinkedHashSet集合:

我们知道HashSet保证元素唯一,可是元素存放进去是没有顺序的,那么我们要保证有序,怎么办呢?

在HashSet下面有一个子类LinkedHashSet,它是链表和哈希表组合的一个数据存储结构。

实例:迭代器遍历有序唯一输出:

//迭代器遍历有序唯一输出
public static void method4(){
LinkedHashSet<String> set=new LinkedHashSet <String>();
set.add("a");
set.add("aabbb");
set.add("张三");
set.add("李四");
set.add("a");
set.add("李四");
Iterator it=set.iterator();
while(it.hasNext()){
System.out.println(it.next());
}

运行结果:按照存储顺序打印

四、 判断集合元素唯一的原理

 4.1ArrayList的contains方法判断元素是否重复原理

ArrayList的contains方法会使用调用方法时,传入的元素的equals方法依次与集合中的旧元素所比较,从而根据返回的布尔值判断是否有重复元素。

(true则有,false则无)。此时,当ArrayList存放自定义类型时,由于自定义类型在未重写equals方法前,判断是否重复的依据是地址值,

所以如果想根据内容判断是否为重复元素,需要重写元素的equals方法。

4.2HashSet的add/contains等方法判断元素是否重复原理

Set集合不能存放重复元素,其添加方法在添加时会判断是否有重复元素,有重复不添加,没重复则添加。

HashSet集合由于是无序的,其判断唯一的依据是元素类型的hashCode与equals方法的返回结果。规则如下:

先判断新元素与集合内已经有的旧元素的HashCode值

l  如果不同,说明是不同元素,添加到集合。

l  如果相同,再判断equals比较结果。返回true则相同元素;返回false则不同元素,添加到集合。

所以,使用HashSet存储自定义类型,如果没有重写该类的hashCode与equals方法,则判断重复时,使用的是地址值,如果想通过内容比较元素是否相同,

需要重写该元素类的hashcode与equals方法。

Java学习(set接口、HashSet集合)的更多相关文章

  1. Java学习笔记27(集合框架一:ArrayList回顾、Collection接口方法)

    集合:集合是java中提供的一种容器,可以用来存储多个数据 集合和数组的区别: 1.数组的长度是固定的,集合的长度是可变的 2.集合中存储的元素必须是引用类型数据 对ArrayList集合的回顾 示例 ...

  2. Java API —— Set接口 & HashSet类 & LinkedHashSet类

    1.Set接口     1)Set接口概述         一个不包含重复元素的 collection,无序(存储顺序和取出顺序不一致),唯一.  (List有序,即存储顺序和取出顺序一致,可重复) ...

  3. java内部类、接口、集合框架、泛型、工具类、实现类

    .t1 { background-color: #ff8080; width: 1100px; height: 40px } 一.内部类 1.成员内部类. (1)成员内部类的实例化: 外部类名.内部类 ...

  4. Java学习笔记-基础语法Ⅶ-集合

    集合 集合类特点:提供一种存储空间可变的存储模型,存储的数据容量可以随时发生改变 这里需要回顾一下,因为数组和字符串一旦创建,就不可改变,需要区分一下 import java.util.ArrayLi ...

  5. Set接口——HashSet集合

    不重复,无索引,不能重复元素,没有索引: HashSet集合: 此时实现Set接口,有哈希表(HashMap的一个实例)支持,哈希表意味着查询速度很快, 是无序的,即元素的存取的顺序可能不一致: 且此 ...

  6. Java学习之接口概念

    Java语言只支持单重继承,不支持多继承,即一个类只能有一个父类.但是在实际应用中,又经常需要使用多继承来解决问题.为了解决该问题,Java语言提供接口来实现类的多继承问题. 接口(英文interfa ...

  7. Java学习:接口(interface)的使用于注意事项

    接口 接口就是一种公共的规范标准.只要符合规范标准,就可以大家通用. 接口就是多个类的公共规范.接口是一种引用数据类型,最重要的内容就是其中的:抽象方法. 如何定义一个接口的格式 如何定义一个接口的格 ...

  8. Java学习笔记31(集合框架五:set接口、哈希表的介绍)

    set接口的特点: 1.不包含重复元素 2.set集合没有索引,只能用迭代器或增强for循环遍历 3.set的底层是map集合 方法和Collection的方法基本一样 set接口的实现类HashSe ...

  9. Java学习笔记32(集合框架六:Map接口)

    Map接口与Collection不同: Collection中的集合元素是孤立的,可理解为单身,是一个一个存进去的,称为单列集合 Map中的集合元素是成对存在的,可理解为夫妻,是一对一对存进去的,称为 ...

  10. Java学习笔记30(集合框架四:List接口)

    List接口继承自Collection接口 具有重要的三大特点: 1.有序集合:存入和取出的顺序一致 2.此接口的用户可以对列表中每个元素插入位置精确的控制:可以通过索引操作 3.可以存储重复元素 L ...

随机推荐

  1. HTML常用标签-<body>内基本标签(块级标签和内联标签)

    HTML常用标签-<body>内基本标签(块级标签和内联标签) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.<hn>系列标签 n的取值范围是1~6,从 ...

  2. RGB色彩对照表

    RGB色彩对照表   #FFFFFF   #FFFFF0   #FFFFE0   #FFFF00   #FFFAFA   #FFFAF0   #FFFACD   #FFF8DC   #FFF68F   ...

  3. 视音频数据处理入门:H.264视频码流解析

    ===================================================== 视音频数据处理入门系列文章: 视音频数据处理入门:RGB.YUV像素数据处理 视音频数据处理 ...

  4. MyEclipse和Eclipse中jsp、html格式化自动排版问题

    一.myeclipse的漂亮排版设置 步骤: 在左侧快捷 “搜索” 框里面输入 html . 点击选中左侧HTML Source . line - width 是设置当前行里面有多少字符时,就换行.这 ...

  5. call 大佬 help7——kmp 补齐 循环节

    http://acm.hdu.edu.cn/showproblem.php?pid=3746 用kmp算法,那么 但是也等于上面的是正确的 也等于下面是错误的 why? #include<cst ...

  6. radioButton drawable selector

    1.实现radioButton drawable selector更改图片,在drawable文件夹下,新建selector文件, <selector xmlns:android="h ...

  7. 用JS获得QQ号码的昵称,头像,生日

    有一个网址,可以返回我们要的内容. http://r.qzone.qq.com/cgi-bin/user/cgi_personal_card?uin=指定QQ号码 将会返回下列内容: _Callbac ...

  8. 【BZOJ】2434: [Noi2011]阿狸的打字机 AC自动机+树状数组+DFS序

    [题意]阿狸喜欢收藏各种稀奇古怪的东西,最近他淘到一台老式的打字机.打字机上只有28个按键,分别印有26个小写英文字母和'B'.'P'两个字母. 经阿狸研究发现,这个打字机是这样工作的: l 输入小写 ...

  9. laravel二维数组手动分页显示

    示例:数组 $user 如下 $user: array (size=) 'sort' => array (size=) => float 0.028616622341171 => f ...

  10. python正则表达式-re模块的爱恨情仇

    利用python的re模块,使用正则表达式对字符串进行处理 # 编辑者:闫龙 import re restr = "abccgccc123def456ghi789jgkl186000&quo ...