Java基础--HashMap面试题

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * HashMap问题
 * @author 15735400536
 * 使用HashMap,如果key是自定义的类,就必须重写hashcode()和equals()
 * 使用ArrayList,如果元素是自定义的类,要做相等判断,就必须重写hashCode()和equals()
 */
public class HashMapTest {

	public static void main(String[] args) {
		Map<User,Doc> hashMap = new HashMap<User,Doc>();

		hashMap.put(new User("mxh","mxh"), new Doc("mxh","mxh"));
		hashMap.put(new User("root","root"), new Doc("root","root"));
		hashMap.put(new User("admin","admin"), new Doc("admin","admin"));

		//再不重写hashCode方法和equals方法的情况下get()方法拿到的结果为null
		//原因: new一个新的对象时,地址变了,不能保证hash值和equals结果还是一样。所以取不到对应的value。
		Object object = hashMap.get(new User("admin","admin"));
		System.out.println(object);

		List<Doc> list = new ArrayList<Doc>();
		list.add(new Doc("三国演义","罗贯中"));
		list.add(new Doc("红楼梦","曹雪芹"));
		list.add(new Doc("水浒传","施耐庵"));
		list.add(new Doc("西游记","吴承恩"));

		//Doc类未重写hashCode()和equals()方法前,结果为false
		boolean result = list.contains(new Doc("水浒传","施耐庵"));
		System.out.println("list集合是否存在该元素: " + result);
	}
}

/**
 * 用户
 * @author 15735400536
 *
 */
class User {
	private String username;
	private String password;
	public String getUsername() {
		return username;
	}
	public void setUsername(String username) {
		this.username = username;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}
	public User(String username, String password) {
		super();
		this.username = username;
		this.password = password;
	}
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((password == null) ? 0 : password.hashCode());
		result = prime * result + ((username == null) ? 0 : username.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;
		User other = (User) obj;
		if (password == null) {
			if (other.password != null)
				return false;
		} else if (!password.equals(other.password))
			return false;
		if (username == null) {
			if (other.username != null)
				return false;
		} else if (!username.equals(other.username))
			return false;
		return true;
	}

}

/**
 * 文档
 * @author 15735400536
 *
 */
class Doc {
	private String title;
	private String content;
	public String getTitle() {
		return title;
	}
	public void setTitle(String title) {
		this.title = title;
	}
	public String getContent() {
		return content;
	}
	public void setContent(String content) {
		this.content = content;
	}
	public Doc(String title, String content) {
		super();
		this.title = title;
		this.content = content;
	}
	@Override
	public String toString() {
		return "Doc [title=" + title + ", content=" + content + "]";
	}
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((content == null) ? 0 : content.hashCode());
		result = prime * result + ((title == null) ? 0 : title.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;
		Doc other = (Doc) obj;
		if (content == null) {
			if (other.content != null)
				return false;
		} else if (!content.equals(other.content))
			return false;
		if (title == null) {
			if (other.title != null)
				return false;
		} else if (!title.equals(other.title))
			return false;
		return true;
	}

}

  1.hashcode()和equals()是在哪里被用到的?什么用的?

  HashMap是基于散列函数,以数组和链表的方式实现的。而对于每一个对象,通过其hashCode()方法可为其生成一个整形值(散列码),该整型值被处理后,将会作为数组下标,存放该对象所对应的Entry(存放该对象及其对应值)。equals()方法则是在HashMap中插入值或查询时会使用到。当HashMap中插入 值或查询值对应的散列码与数组中的散列码相等时,则会通过equals方法比较key值是否相等,所以想以自建对象作为HashMap的key,必须重写 该对象继承object的equals方法。

  2.本来不就有hashcode()和equals()了么?干嘛要重写,直接用原来的不行么?

  HashMap中,如果要比较key是否相等,要同时使用这两个函数!因为自定义的类的hashcode()方法继承于Object类,其hashcode码为默认的内存地址,这样即便有相同含义的两个对象,比较也是不相等的。

  Doc doc1 = new Doc("三国演义","罗贯中");
  Doc doc2 = new Doc("三国演义","罗贯中");

  正常理解这两个对象存入到hashMap中应该是相等的,但如果你不重写 hashcode()方法的话,比较是其地址,不相等!

  HashMap中的比较key是这样的,先求出key的hashcode(),比较其值是否相等,若相等再比较equals(),若相等则认为他们是相等 的。若equals()不相等则认为他们不相等。如果只重写hashcode()不重写equals()方法,当比较equals()时只是看他们是否为 同一对象(即进行内存地址的比较),所以必定要两个方法一起重写。HashMap用来判断key是否相等的方法,其实是调用了HashSet判断加入元素 是否相等。

原文地址:https://www.cnblogs.com/mxh-java/p/11048700.html

时间: 2024-11-05 16:42:09

Java基础--HashMap面试题的相关文章

50道最新java基础部分面试题(二)

java基础部分面试题(前11题请看上一篇博客)12.静态变量和实例变量的区别? 在语法定义上的区别:静态变量前要加static关键字,而实例变量前则不加.在程序运行时的区别:实例变量属于某个对象的属性,必须创建了实例对象,其中的实例变量才会被分配空间,才能使用这个实例变量.静态变量不属于某个实例对象,而是属于类,所以也称为类变量,只要程序加载了类的字节码,不用创建任何实例对象,静态变量就会被分配空间,静态变量就可以被使用了.总之,实例变量必须创建对象后才可以通过这个对象来使用,静态变量则可以直

【面试题】Java基础部分面试题

Java基础面试题 Equals与==的区别 使用==比较原生类型如:boolean,,int,char等等,  使用equals()比较对象. 1.  ==是判断两个变量或类型是不是指向同一个内存空间, equals是判断两个变量或实例所指向的内存空间的值是不是相同. 2. ==是指对内存地址进行比较,equals()是对字符串的内容进行比较 3. ==指引用是否相同, equals()指的是值是否相同. 自动拆装箱 自动装箱是将一个Java定义的基本数据类型赋值给相应封装类的变量, 拆箱与装

不惑JAVA之JAVA基础 - HashMap

HashMap应该是平时应用开发中或是框架设计中最为常用高效的容器.在介绍HashMap之前,先介绍两个常见的区别.后期会专门介绍CurrentHashMap. hashmap 和 hashtable 区别 HashMap和HashTable有什么区别,一个比较简单的回答是: HashMap是非线程安全的,HashTable是线程安全的. HashMap的键和值都允许有null值存在,而HashTable则不行. 因为线程安全的问题,HashMap效率比HashTable的要高. hashmap

2019年最新50道java基础部分面试题

[软帝学院]1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语法,集合的语法,io 的语法,虚拟机方面的语法. 1.一个".java"源文件中是否可以包括多个类(不是内部类)?有什么限制?  可以有多个类,但只能有一个public的类,并且public的类名必须与文件名相一致. 2.Java有没有goto?  java中的保留字,现在没有在java中使用. 3.说说&和&&的区别.  &和&

80道最新java基础部分面试题(六)

自己整理的面试题,希望可以帮到大家,需要更多资料的可以私信我哦,大家一起学习进步! 59.ArrayList和Vector的区别 答: 这两个类都实现了List接口(List接口继承了Collection接口),他们都是有序集合,即存储在这两个集合中的元素的位置都是有顺序的,相当于一种动态的数组,我们以后可以按位置索引号取出某个元素,,并且其中的数据是允许重复的,这是HashSet之类的集合的最大不同处,HashSet之类的集合不可以按索引号去检索其中的元素,也不允许有重复的元素(本来题目问的与

80道最新java基础部分面试题(七)

自己整理的面试题,希望可以帮到大家,需要更多资料的可以私信我哦,大家一起学习进步! 70.TreeSet里面放对象,如果同时放入了父类和子类的实例对象,那比较时使用的是父类的compareTo方法,还是使用的子类的compareTo方法,还是抛异常!  (应该是没有针对问题的确切的答案,当前的add方法放入的是哪个对象,就调用哪个对象的compareTo方法,至于这个compareTo方法怎么做,就看当前这个对象的类中是如何编写这个方法的) 实验代码: public class Parent i

[Java基础]HashMap的那些事

提到HashMap,使用Java语言的人来说,是再熟悉不过了.今天就简单聊聊我们认识的HashMap; 首先我们看一下Java中的HashMap类 public class HashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>, Cloneable, Serializable { private static final long serialVersionUID = 362498820763181265L;

java 基础 ---HashMap、HashTable

HashMap.HashTable区别. 1.HashMap线程不安全,HashTable线程安全: 2.HashMap的键和值都允许null值存在,而HashTable不允许: 3.HashMap的效率高于Hashtable * Hash table based implementation of the <tt>Map</tt> interface.  This * implementation provides all of the optional map operatio

Java基础——HashMap源码分析

本篇介绍的HashMap综合了ArrayList和LinkedList这两个集合的优势,它的底层是基于哈希表实现的,如果不考虑哈希冲突的话,HashMap在增删改查操作上的时间复杂度都能够达到惊人的O(1). 对于HashMap类源码中开头注释翻译: HashMap基于哈希表的 Map 接口的实现.此实现提供所有可选的映射操作,并允许使用 null 值和 null 键.(除了不同步和允许使用 null 之外,HashMap 类与 Hashtable 大致相同.)此类不保证映射的顺序,特别是它不保