Skip to content

Instantly share code, notes, and snippets.

@zhugw
Last active May 16, 2017 09:43
Show Gist options
  • Save zhugw/b5beb900ac101066c73e867e6dc9d9b2 to your computer and use it in GitHub Desktop.
Save zhugw/b5beb900ac101066c73e867e6dc9d9b2 to your computer and use it in GitHub Desktop.
The effect of an object with or without euqals and hashCode as a hashmap key
package interview;
import org.junit.Test;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import static org.junit.Assert.*;
/**
* 面试题:
* 考察作为HashMap的key的对象有无复写equals和hashCode时的表现
* Created by zhuguowei on 5/16/17.
*/
public class HashMapTest {
@Test
public void test_StudentWithOutEqualAndHashCode() throws Exception {
StudentWithOutEqualAndHashCode student1 = new StudentWithOutEqualAndHashCode("zhangsan");
StudentWithOutEqualAndHashCode student2 = new StudentWithOutEqualAndHashCode("zhangsan");
assertFalse(student1 == student2); // false
assertFalse(student1.equals(student2)); // false
Map<StudentWithOutEqualAndHashCode, Integer> map = new HashMap<>();
map.put(student1, 1);
map.put(student2, 2);
assertEquals(2,map.size()); // 2
assertEquals(1,map.get(student1).intValue());
assertEquals(2,map.get(student2).intValue());
printTable(map);
}
@Test
public void test_StudentWithHashCode() throws Exception {
StudentWithHashCode student1 = new StudentWithHashCode("zhangsan");
StudentWithHashCode student2 = new StudentWithHashCode("zhangsan");
assertFalse(student1 == student2); // false
assertFalse(student1.equals(student2)); // false
HashMap<StudentWithHashCode, Integer> map = new HashMap<>();
map.put(student1, 1);
map.put(student2, 2);
assertEquals(2,map.size()); // 2
assertEquals(1,map.get(student1).intValue());
assertEquals(2,map.get(student2).intValue());
printTable(map);
Object[] table = getTable(map);
assertEquals(student1, getStudent(student1.hashCode(), table,0));
assertEquals(student2, getStudent(student2.hashCode(), table,1));
}
@Test
public void test_StudentWithHashCodeAndEquals() throws Exception {
StudentWithHashCodeAndEquals student1 = new StudentWithHashCodeAndEquals("zhangsan");
StudentWithHashCodeAndEquals student2 = new StudentWithHashCodeAndEquals("zhangsan");
assertFalse(student1 == student2); // false
assertTrue(student1.equals(student2)); // true
HashMap<StudentWithHashCodeAndEquals, Integer> map = new HashMap<>();
map.put(student1, 1);
map.put(student2, 2);
assertEquals(1,map.size());
assertEquals(2,map.get(student1).intValue());
assertEquals(2,map.get(student2).intValue());
printTable(map);
Object[] table = getTable(map);
assertEquals(student1, getStudent(student1.hashCode(), table,0));
assertNull(getStudent(student1.hashCode(), table,1));
}
private Student getStudent(int hashCode, Object[] table, int nextIndex) throws NoSuchFieldException, IllegalAccessException {
int i = (hashCode ^ (hashCode >>> 16)) & (16 - 1);
Object node = table[i];
for (int j = 0; j < nextIndex; j++) {
Field nextField = node.getClass().getDeclaredField("next");
nextField.setAccessible(true);
node = nextField.get(node);
}
if(node == null){
return null;
}
Field keyField = node.getClass().getDeclaredField("key");
keyField.setAccessible(true);
return (Student) keyField.get(node);
}
private void printTable(Map map) throws NoSuchFieldException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
Object[] table = getTable(map);
System.out.println(Arrays.toString(table));
}
private Object[] getTable(Map map) throws NoSuchFieldException, IllegalAccessException {
Field tableField = HashMap.class.getDeclaredField("table");
tableField.setAccessible(true);
return (Object[]) tableField.get(map);
}
interface Student{}
static class StudentWithOutEqualAndHashCode implements Student{
private String name;
public StudentWithOutEqualAndHashCode(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
static class StudentWithHashCode implements Student{
private String name;
public StudentWithHashCode(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public int hashCode() {
return 1;
}
}
static class StudentWithHashCodeAndEquals implements Student{
private String name;
public StudentWithHashCodeAndEquals(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public int hashCode() {
return 1;
}
@Override
public boolean equals(Object obj) {
return true;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment