Java学习笔记31(集合框架五:set接口、哈希表的介绍)
set接口的特点:
1.不包含重复元素
2.set集合没有索引,只能用迭代器或增强for循环遍历
3.set的底层是map集合
方法和Collection的方法基本一样
set接口的实现类HashSet:
1.无序集合
2.可以存入空(null)
3.不可以存在重复元素
示例:
package demo; import java.util.HashSet;
import java.util.Iterator;
import java.util.Set; public class HashSetDemo {
public static void main(String[] args) {
Set<String> set = new HashSet<String>();
set.add("abc1");
set.add("abc1");
set.add("abc2");
set.add("abc3");
set.add("abc4");
Iterator<String> i1 = set.iterator();
while(i1.hasNext()){
System.out.println(i1.next());
}
}
}
/*
输出:
注意:这里的输出特点是无序的
abc1
abc4
abc2
abc3
*/
set底层数据结构是哈希表:
特点:存储取出都比较快
原理:具体省略,简单说就是链表数组结合体
对象的哈希值:普通的一个整数
可以理解为身份证号,是hashset存储的依据
package demo;
public class Person {}
package demo;
public class HashDemo {
public static void main(String[] args) {
Person p = new Person();
int i = p.hashCode();
System.out.println(i);
//每次运行都会输出不同的整数,比如1191201656
String s1 = new String("abc");
String s2 = new String("abc");
System.out.println(s1.hashCode());//
System.out.println(s2.hashCode());//96354
//这里Stirng重写hashcode方法,有对应的计算公式
//当字符串的内容相同时候,运算结果就相同,因此s1和s2的哈希值相同
}
}
哈希表存储过程:
1.调用对象的哈希值
2.集合在容器内搜索有没有重复的哈希值,如果没有,存入新元素,记录哈希值
3.再次存储,重复上边的过程
4.如果有重复的哈希值,调用后来者的equals方法,参数为前来者,结果得到true,集合判断为重复元素,不存入
相同的字符串如果存进去,哈希值相同,equals方法为true,不会存入相同的
只要哈希值相同或者equals方法为true都成立才不会存入,只要其中一条不满足,都会储存
哈希表存储自定义对象:
package demo;
public class Person {
private String name;
private int 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;
}
public String toString() {
return this.name + ":" + this.age;
}
public Person() {
}
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
}
package demo;
import java.util.HashSet;
public class HashDemo {
public static void main(String[] args) {
HashSet<Person> setPerson = new HashSet<Person>();
setPerson.add(new Person("a",17));
setPerson.add(new Person("b",20));
setPerson.add(new Person("b",20));
setPerson.add(new Person("c",18));
System.out.println(setPerson);
//[c:18, b:20, a:17, b:20]
//发现存入了重复的元素
//所以想办法使name和age相同的Person对象视为同一个对象
//所以需要重写hashcode方法
}
}
自己重写:
package demo;
public class Person {
private String name;
private int 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;
}
public String toString() {
return this.name + ":" + this.age;
}
public Person() {
}
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
public int hashCode(){
return name.hashCode()+age*66;
}
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;
}
}
eclipse可以帮助我们写:
package demo;
public class Person {
private String name;
private int 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;
}
public String toString() {
return this.name + ":" + this.age;
}
public Person() {
}
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + age;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Person other = (Person) obj;
if (age != other.age)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
}
LinkedHashSet集合:基于链表的哈希表实现,继承HashSet,它具有顺序
示例:
package demo;
import java.util.LinkedHashSet;
public class LinkedHashSetDemo {
public static void main(String[] args) {
//有序的set
LinkedHashSet<Integer> link = new LinkedHashSet<Integer>();
link.add(1);
link.add(2);
link.add(3);
link.add(4);
System.out.println(link);
//[1, 2, 3, 4]
}
}
关于hashcode和equals的一些问题,在面试中会问道:
1.两个对象哈希值相同,那么equals方法一定返回true吗?不一定
取决于如何重写equals,如果重写固定了它返回false,结果就一定是false
2.equals方法返回true,那么哈希值一定相同吗?一定
如果类中定义一个静态变量(static int a = 1),然后重写hashcode返回a+1,那么每一个对象的哈希值都不一样
不过java中规定:对象相等,必须具有相同的哈希码值,所以这里是一定的
Java学习笔记31(集合框架五:set接口、哈希表的介绍)的更多相关文章
- 【Java学习笔记】<集合框架>定义功能去除ArrayList中的重复元素
import java.util.ArrayList; import java.util.Iterator; import cn.itcast.p1.bean.Person; public class ...
- 【Java学习笔记】<集合框架>对字符串进行长度排序
package 测试; import java.util.Comparator; public class ComparatorByLength implements Comparator { //定 ...
- 【Java学习笔记】<集合框架>TreeSet,Comparable,Comparator
public class Person implements Comparable{ private String name; private int age; public Person(){ su ...
- Java学习笔记之---集合
Java学习笔记之---集合 (一)集合框架的体系结构 (二)List(列表) (1)特性 1.List中的元素是有序并且可以重复的,成为序列 2.List可以精确的控制每个元素的插入位置,并且可以删 ...
- Java学习笔记31(IO:Properties类)
Properties类,表示一个持久的j集,可以存在流中,或者从流中加载 是Hashtable的子类 map集合的方法都能用 用途之一:在开发项目中,我们最后交给客户的是一个编译过的class文件,客 ...
- Java基础学习笔记十七 集合框架(三)之Map
Map接口 通过查看Map接口描述,发现Map接口下的集合与Collection接口下的集合,它们存储数据的形式不同,如下图. Collection中的集合,元素是孤立存在的(理解为单身),向集合中存 ...
- 【原】Java学习笔记026 - 集合
package cn.temptation; public class Sample01 { public static void main(String[] args) { // 需求:从三国演义中 ...
- JavaSE 学习笔记之集合框架(十八)
集合框架:,用于存储数据的容器. 特点: 1:对象封装数据,对象多了也需要存储.集合用于存储对象. 2:对象的个数确定可以使用数组,但是不确定怎么办?可以用集合.因为集合是可变长度的. 集合和数组的区 ...
- Java学习笔记之集合
集合(Collection)(掌握) (1)集合的由来? 我们学习的是Java -- 面向对象 -- 操作很多对象 -- 存储 -- 容器(数组和StringBuffer) -- 数组而数组的长度固定 ...
随机推荐
- 吴裕雄 python深度学习与实践(7)
import cv2 import numpy as np img = np.mat(np.zeros((,))) cv2.imshow("test",img) cv2.waitK ...
- Echarts 饼状图自定义颜色
今天给饼状图着色问题,找了好久 终于找到了 话不多说直接上代码 $.ajax({ url: "/HuanBaoYunTai/ajax/HuanBaoYunTaiService.ashx&qu ...
- vi 操作
vi 3种模式:1命令行模式,2插入模式,3末行模式 Vim启动后直接进入的是命令行模式,命令行模式顾名思义就是可以输入各种命令的意思, 1. 命令行下按i键进入“插入模式”,命令行下按:键进入“末行 ...
- java学习笔记(八):继承、extends、super、this、final关键字
继承解决代码重用的问题,方便管理和维护代码. 继承 子类拥有父类非private的属性,方法. 子类可以拥有自己的属性和方法,即子类可以对父类进行扩展. 子类可以用自己的方式实现父类的方法. Java ...
- Apache无法正常启动(配置多个监听端口)
Apache监测多个端口配置: 1.conf->extra->httpd-vhosts.conf 检查配置项是否写错 2.http.conf listen端口是否监听正确 3.环境变量中 ...
- 记录----第一次使用BFS(广度搜索)学习经验总结
学习经验记录与分享—— 最近在学习中接触到了一种解决最短路径的实用方法----BFS(广度搜索),在这里总结并分享一下第一次学习的经验. 首先第一个要了解的是"queue"(队列函 ...
- 41 【docker】初识
常用的docker命令: docker ps #查看当前正在运行的容器 docker ps -a | grep <keyword> #查看所有的容器,运行的或者停止的 docker sto ...
- 150. Evaluate Reverse Polish Notation逆波兰表达式
[抄题]: Evaluate the value of an arithmetic expression in Reverse Polish Notation. Valid operators are ...
- [BeijingWc2008]雷涛的小猫
--BZOJ1270 Description 雷涛的小猫雷涛同学非常的有爱心,在他的宿舍里,养着一只因为受伤被救助的小猫(当然,这样的行为是违反学生宿舍管理条例的). 在他的照顾下,小猫很快恢复了健康 ...
- Vc 检测内存泄漏
启用内存泄漏检测 检测内存泄漏是 C/c + + 调试器和 C 运行时库 (CRT) 的主要工具调试堆函数. 若要启用调试堆的所有函数,在 c + + 程序中,按以下顺序包含以下语句: C++复制 # ...