Skip to content

Commit b2816d9

Browse files
committed
hashcode、equals
1 parent 4919a23 commit b2816d9

File tree

5 files changed

+130
-63
lines changed

5 files changed

+130
-63
lines changed

Interview/sad/hashcode、equals.md

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
> 我感觉这问题被问的频率有点高
2+
3+
面试官:出个题:
4+
5+
```java
6+
Integer a = new Integer(5);
7+
Integer b = new Integer(5);
8+
System.out.println(a == b); // false
9+
```
10+
11+
我:false,太简单了嘛。 == 比较的是两个对象的地址哦,你看:
12+
13+
它的作用是**判断两个对象的地址是不是相等**。即,判断两个对象是不是同一个对象:
14+
15+
- 基本数据类型==比较的是****
16+
17+
- 引用数据类型==比较的是**内存地址**
18+
19+
你要是:`System.out.println(a.equals(b)); \\ false`
20+
21+
面试官:那这个呢:
22+
23+
```java
24+
int a = 5;
25+
Integer b = new Integer(5);
26+
System.out.println(a == b); // true
27+
```
28+
29+
我:你想考我装箱拆箱嘛?其实,b看到了对面那个哥们是**基本类型**,我也是基本类型包装的呀,我把衣服一脱,那么就是**基本类型**了,那就是上面的结论了。b拆箱即可。
30+
31+
装箱:**自动将基本数据类型转换为包装器类型**
32+
33+
拆箱:**自动将包装器类型转换为基本数据类型**
34+
35+
基本类型有:
36+
37+
- byte(1字节):Byte
38+
- short(2字节):Short
39+
- int(4字节):Integer
40+
- long(8字节):Long
41+
- float(4字节):Float
42+
- double(8字节):Double
43+
- char(2字节):Character
44+
- boolean(未知):Boolean
45+
46+
**在装箱的时候自动调用的是Integer的valueOf(int)方法。而在拆箱的时候自动调用的是Integer的intValue方法**
47+
48+
valueOf:
49+
50+
```java
51+
public static Integer valueOf(int i) {
52+
if (i >= IntegerCache.low && i <= IntegerCache.high)
53+
return IntegerCache.cache[i + (-IntegerCache.low)];
54+
return new Integer(i);
55+
}
56+
```
57+
58+
intValue:
59+
60+
```java
61+
public int intValue() {
62+
return value;
63+
}
64+
```
65+
66+
面试官:聊一下equals
67+
68+
我:equals是顶层父类Object的方法之一
69+
70+
```java
71+
// 你看,object默认调用的== , 你对象如果不重写,可能会发上重大事故
72+
public boolean equals(Object obj) {
73+
return (this == obj);
74+
}
75+
```
76+
77+
顺带说一下Object的hashcode方法
78+
79+
```java
80+
// Returns a hash code value for the object.
81+
// 说白了,返回的就是该对象的地址值
82+
public native int hashCode();
83+
```
84+
85+
Equals的作用也是判断两个对象是否相等。但它一般有两种使用情况:
86+
87+
- 情况1:类没有覆盖 equals() 方法。则通过 equals() 比较该类的两个对象时,等价于通过`==`比较这两个对象。
88+
89+
- 情况2:类覆盖了 equals() 方法。一般,我们都覆盖 equals() 方法来比较两个对象的内容是否相等;若它们的内容相等,则返回 true (即,认为这两个对象相等)。
90+
91+
```java
92+
Integer a = new Integer(5);
93+
Integer b = new Integer(5);
94+
System.out.println(a.equals(b));
95+
```
96+
97+
可以看一下Integer的equals方法:
98+
99+
```java
100+
// 重写了Object的equals的方法
101+
public boolean equals(Object obj) {
102+
if (obj instanceof Integer) {
103+
// 比较value
104+
return value == ((Integer)obj).intValue();
105+
}
106+
return false;
107+
}
108+
```
109+
110+
hashcode的例子:
111+
112+
```java
113+
public static void main(String[] args) {
114+
Set<Integer> set = new HashSet<>();
115+
set.add(1);
116+
set.add(1);
117+
System.out.println(set.toString());
118+
}
119+
```
120+
121+
在添加1的时候,先判断hashcode是否相同,如果相同,继续判断equals比较值,这样的好处是,如果hashcode相同就直接返回false了,减少了一次equals的判断,因为通常hashcode的值判断是否相等比较快,而equals相对于hashcode来讲慢一些。所以,如果不重写hashcode,我们看到object的hashcode是对象的内存值,那么set添加1判断的时候,hashcode永远不相等,那么就永远返回false,不管添加1,还是2,都是false。

Interview/sad/谈谈集合.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545
- 线程B也发现需要大小为10,也可以容纳,返回。
4646
- 好了,**问题来了哈**
4747
- 线程A开始进行设置值操作,elementData[size++] = e操作。此时size变为10。
48-
- 线程B也开始进行设置值操作,它尝试设置elementData[10] = e, 而elementData没有进行过扩容,它的下标最大为
48+
- 线程B也开始进行设置值操作,它尝试设置elementData[10] = e, 而elementData没有进行过扩容,它的下标最大为10
4949
- 于是此时会报出一个数组越界的异常`ArrayIndexOutOfBoundsException`
5050

5151
null

Interview/src/Main.java

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,13 @@
1+
import java.util.HashSet;
2+
import java.util.Set;
3+
14
public class Main {
25
public static void main(String[] args) {
3-
// Scanner sc = new Scanner(System.in);
4-
Integer a = new Integer(5);
5-
Integer b = new Integer(5);
6-
if (a == b)
7-
System.out.println("true");
8-
else
9-
System.out.println("false, 比的是内存地址啊,兄弟");
10-
11-
if (a.equals(b))
12-
System.out.println("True,这就对了嘛,equals干嘛使用?");
13-
else
14-
System.out.println("False");
6+
Set<Integer> set = new HashSet<>();
7+
set.add(1);
8+
set.add(1);
9+
System.out.println(set.toString());
1510
}
16-
17-
1811
}
1912

2013

Interview/src/Solution.java

Lines changed: 0 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,3 @@
1-
import java.util.LinkedList;
2-
import java.util.List;
3-
import java.util.Queue;
4-
51
public class Solution {
62

7-
public int ladderLength(String beginWord, String endWord, List<String> wordList) {
8-
if (!wordList.contains(endWord))
9-
return 0;
10-
boolean[] marked = new boolean[wordList.size()]; // 可以set
11-
//检验是否存在beginWord,如果存在,就置为访问过了,没必要访问
12-
int idx = wordList.indexOf(beginWord);
13-
if (idx != -1)
14-
marked[idx] = true;
15-
Queue<String> q = new LinkedList<>();
16-
q.add(beginWord);
17-
int cnt = 0;
18-
while (!q.isEmpty()) {
19-
int size = q.size();
20-
cnt++;
21-
while (size-- > 0) {
22-
String start = q.poll();
23-
for (int i = 0; i < wordList.size(); i++) {
24-
// 访问过了
25-
if (marked[i])
26-
continue;
27-
String s = wordList.get(i);
28-
//不满足和当前只差一个字符不同,跳过,访问下一个
29-
if (!isConnect(start, s))
30-
continue;
31-
//和endWord匹配上了,进行返回,因为是bfs,所以找到了直接返回就是最短的
32-
if (s.equals(endWord))
33-
return cnt+1;
34-
q.add(s);
35-
marked[i] = true;
36-
}
37-
}
38-
}
39-
return 0;
40-
}
41-
42-
private boolean isConnect(String s1, String s2) {
43-
int diffCnt = 0;
44-
for (int i = 0; i < s1.length() && diffCnt <= 1; i++) {
45-
if (s1.charAt(i) != s2.charAt(i)) {
46-
diffCnt++;
47-
}
48-
}
49-
return diffCnt == 1;
50-
}
513
}

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
## 我是这样回答的
3535
> 能力有限,但又想去钻研,面试中该怎么回答较好。(持续总结...)
3636
37+
- [hashcode、equals](/Interview/sad/hashcode、equals.md)
3738
- [谈谈异常机制](/Interview/sad/谈谈异常机制.md)
3839
- [谈谈反射机制](/Interview/sad/谈谈反射机制.md)
3940
- [谈谈多态](/Interview/sad/谈谈多态.md)

0 commit comments

Comments
 (0)