## Java專題二:相等與比較
[TOC]
### 2.1.運算符==
基本數據類型(byte、short、int、long、char、float、double、boolean):判斷數值是否相等
引用數據類型(類的對象):判斷對象的地址是否相等,一般通過new關鍵詞創建的對象都是不相等的。
### 2.2.equals方法
**equals方法是判斷對象相等最常使用的方法。**
如:
在ArrayList中判斷是否包含某元素contains方法:
1.判斷是否待查找的對象是否為null,為null的話,進入第2步,否則進入第3步
2.遍歷ArrayList的元素數組,查找是否數組中包含null,查找結束
3.遍歷ArrayList的元素數組,調用每個元素的equals方法,判斷是否相等
**說明:**
如果2個對象的equals方法相等,則它們的hashCode方法一定會要產生相同的整形值,所以在定義類重載equals時候最好重寫hashCode方法。
**定義equals方法一般原則**:
1. 判斷this對象與anObject對象是否相等(`this == anObject`)
2. 判斷anObject對象是否為類或其子類對象(`anObject instanceof String`)
3. 比較類中屬性是否相等
基本類型,直接使用==判斷
集合數組類型,遍歷集合數組使用相應equals方法判斷
引用數據類型,使用相應equals方法判斷
4. 重寫equals方法是總要重寫hashCode方法(Always override hashCode when you override equals)
如String類的equals方法:
```java
// java.lang.String#equals
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = value.length;
if (n == anotherString.value.length) {
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}
```
### 2.3.hashCode方法
如:
HashMap的Hash表結構中,使用哈希函數定位元素的位置就是通過元素的hash值,即(h = key.hashCode()) ^ (h >>> 16);因此如果2個對象的hashCode返回相同的值,意味著產生沖突或者是同一個元素(Key的equals方法相等)
**定義hashCode方法一般原則**:
1. 定義int類型變量hashCode并賦值1(`int hashCode = 1;`)
2. 對于每個成員變量,進行如下計算hash code `c`(根據字段類型):
boolean: ` (f ? 1 : 0)`
byte, char, short, int: `(int) f`
long: `(int) (f ^ (f >>> 32))`
float: `Float.floatToIntBits(f)`
double: `Double.doubleToLongBits(f)`
Object: `(obj==null ? 0 : obj.hashCode())`
3. 對每個字段進行如下操作: `hashCode = 31 * hashCode + c;`
4. 返回hashCode(`return hashCode;`)
```java
//java.util.AbstractList#hashCode
public int hashCode() {
int hashCode = 1;
for (E e : this)
hashCode = 31*hashCode + (e==null ? 0 : e.hashCode());
return hashCode;
}
```
### 2.4.Comparable接口與Comparator接口
涉及數組或列表有序存儲或排序問題,如TreeMap自動排序和Arrays.sort方法,public static <T> void sort(T[] a, Comparator<? super T> c),都需要比較大小。
```java
public interface Comparable<T> {
public int compareTo(T o);
}
```
```java
public interface Comparator<T> {
int compare(T o1, T o2);
}
```
在使用TreeMap時會對插入鍵值對元素的Key進行排序,必須通過比較排序。而比較就要用到上面2個接口:
**第1種** :在TreeMap構造方法`public TreeMap(Comparator<? super K> comparator)`直接指定一個比較器,操作元素時調用比較器的compare方法實現Key的大小比較;
**第2種** :Key類實現Comparable接口,操作元素時調用Key的compare方法來實現大小的比較。
其它則如下面所示,會拋出異常。
```java
class A{
}
public class TreeMapTest {
public static void main(String[] args){
TreeMap map = new TreeMap<A, String>();
map.put(new A(), "null");;
}
}
```
**運行報異常:** Exception in thread "main" java.lang.ClassCastException: A cannot be cast to java.lang.Comparable
- JavaCook
- Java專題零:類的繼承
- Java專題一:數據類型
- Java專題二:相等與比較
- Java專題三:集合
- Java專題四:異常
- Java專題五:遍歷與迭代
- Java專題六:運算符
- Java專題七:正則表達式
- Java專題八:泛型
- Java專題九:反射
- Java專題九(1):反射
- Java專題九(2):動態代理
- Java專題十:日期與時間
- Java專題十一:IO與NIO
- Java專題十一(1):IO
- Java專題十一(2):NIO
- Java專題十二:網絡
- Java專題十三:并發編程
- Java專題十三(1):線程與線程池
- Java專題十三(2):線程安全與同步
- Java專題十三(3):內存模型、volatile、ThreadLocal
- Java專題十四:JDBC
- Java專題十五:日志
- Java專題十六:定時任務
- Java專題十七:JavaMail
- Java專題十八:注解
- Java專題十九:淺拷貝與深拷貝
- Java專題二十:設計模式
- Java專題二十一:序列化與反序列化
- 附加專題一:MySQL
- MySQL專題零:簡介
- MySQL專題一:安裝與連接
- MySQL專題二:DDL與DML語法
- MySQL專題三:工作原理
- MySQL專題四:InnoDB存儲引擎
- MySQL專題五:sql優化
- MySQL專題六:數據類型
- 附加專題二:Mybatis
- Mybatis專題零:簡介
- Mybatis專題一:配置文件
- Mybatis專題二:映射文件
- Mybatis專題三:動態SQL
- Mybatis專題四:源碼解析
- 附加專題三:Web編程
- Web專題零:HTTP協議
- Web專題一:Servlet
- Web專題二:Cookie與Session
- 附加專題四:Redis
- Redis專題一:數據類型
- Redis專題二:事務
- Redis專題三:key的過期
- Redis專題四:消息隊列
- Redis專題五:持久化