hashCode和equals方法
当使用ide进行开发时,最简单的重写就是用ide自动生成hashCode和equals方法
例如:
package hashcode;
/**
* Created with IntelliJ IDEA.
* User: ASUS
* Date: 14-7-2
* Time: 上午11:25
* To change this template use File | Settings | File Templates.
*/
public class Worker {
public int id;
public String name;
public Worker(int id, String name) {
this.id = id;
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
/**
* 使用ide重写的hashCode和equals
* 两个worker对象比较的id
*
* @param o
* @return
*/
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Worker)) return false;
Worker worker = (Worker) o;
if (id != worker.id) return false;
return true;
}
@Override
public int hashCode() {
return id;
}
}
做一个看一下equals方法和hashCode方法
@Test
public void test909() {
Worker w1 = new Worker(12, "lyx");
Worker w2 = new Worker(12, "yui");
System.out.println(w1 == w2); //false
System.out.println(w1.equals(w2)); //true
System.out.print(w1.hashCode() == w2.hashCode()); //true
}
所以这两个对象只要id相等(两个对象的内存地址是不相同的),虽然name不同,但hashCode值是一样的。(hashCode主要用在集合中进行对象的存取)
Java对于eqauls方法和hashCode方法是这样规定的:
1、如果两个对象相同,那么它们的hashCode值一定要相同;
2、如果两个对象的hashCode相同,它们并不一定相同
上面说的对象相同指的是用eqauls方法比较。
/**
* HashSet
* 当添加对象时,通过对象的hashCode判断是否已经存在该对象
*/
@Test
public void test8989() {
Worker w1 = new Worker(12, "lyx");
Worker w2 = new Worker(12, "yui");
Set<Worker> workers = new HashSet<Worker>();
workers.add(w1);
workers.add(w2);
Iterator it = workers.iterator();
while (it.hasNext()) {
Worker worker = (Worker) it.next();
System.out.println(worker.getId());
}
System.out.println(workers.size()); //1
}
使用HashSet集合存储byte数组
直接看代码
@Test
public void test7878() {
Set<byte[]> hashSet = new HashSet<byte[]>();
byte[] b1 = new byte[]{1, 2, 3};
byte[] b2 = new byte[]{1, 2, 3};
if (b1 instanceof Object) {
System.out.println("b1 instanceof Object!!");
System.out.println(b1.length); //b1作为一个对象,拥有length属性
System.out.println("class name=" + b1.getClass().getName());
}
//字节数组b1和b2有相同的字节元素
hashSet.add(b1);
hashSet.add(b2);
System.out.println(b1.equals(b2)); //false
System.out.println(hashSet.size()); //2
/**
* 使用equals比较b1和b2,是不相等的,但是我要存在HashSet中要把他们看成是相等的
* 所以这里使用ByteBuffer来进行封装byte[]数组
*/
HashSet<ByteBuffer> hashSet1 = new HashSet<ByteBuffer>();
hashSet1.add(ByteBuffer.wrap(b1));
System.out.println(hashSet1.contains(ByteBuffer.wrap(b2))); //true
hashSet1.add(ByteBuffer.wrap(b2));
System.out.println(hashSet1.size()); //1
}
运行结果:
b1 instanceof Object!!
3
class name=[B
false
2
true
1
Process finished with exit code 0
你看ByteBuffer类中equals和hashCode方法
public int hashCode() {
int h = 1;
int p = position();
for (int i = limit() - 1; i >= p; i--)
h = 31 * h + (int)get(i);
return h;
}
public boolean equals(Object ob) {
if (this == ob)
return true;
if (!(ob instanceof ByteBuffer))
return false;
ByteBuffer that = (ByteBuffer)ob;
if (this.remaining() != that.remaining())
return false;
int p = this.position();
for (int i = this.limit() - 1, j = that.limit() - 1; i >= p; i--, j--)
if (!equals(this.get(i), that.get(j)))
return false;
return true;
}
ByteBuffer通过equals和hashcode方法比较的是每个字节是否相同。两个具有相同字节的字节数组封装成ByteBuffer后equals会相等。
字节数组作为key存储在HashSet中
就想上文介绍的那样,使用ByteBuffer封装byte数组,作为key的ByteBuffer存储在HashSet中,那么如果使用byte[]作为key怎么办呢。
一种方法是继承HashSet实现自定义的HashSet
看代码:
package hashcode;
import java.nio.ByteBuffer;
import java.util.HashSet;
public class ByteKeyHashSet extends HashSet<ByteBuffer> {
private static final long serialVersionUID = -2702041216392736060L;
public boolean add(byte[] key) {
return super.add(ByteBuffer.wrap(key));
}
public boolean add(String key) {
return super.add(ByteBuffer.wrap(key.getBytes()));
}
public boolean remove(byte[] key) {
return super.remove(ByteBuffer.wrap(key));
}
public boolean remove(String key) {
return super.remove(ByteBuffer.wrap(key.getBytes()));
}
public boolean contains(byte[] key) {
return super.contains(ByteBuffer.wrap(key));
}
public boolean contains(String key) {
return super.contains(ByteBuffer.wrap(key.getBytes()));
}
}
做一个测试如下
@Test
public void test876() {
ByteKeyHashSet byteKeyHashSet = new ByteKeyHashSet();
byte[] k1 = new byte[]{1, 2, 3};
byte[] k2 = new byte[]{1, 2, 3};
byteKeyHashSet.add(k1);
Assert.assertTrue(byteKeyHashSet.contains(k2)); //true
byteKeyHashSet.remove(k1);
Assert.assertFalse(byteKeyHashSet.contains(k2)); //false
}
Java中数组是对象
1.数组是对象。
2.java.lang.reflect.Array是final的,所以数组肯定不是它的子类这个类用来动态生成数组或者操作数组(获得长度等)。
3.java.util.Arrays是一个数组操作应用类,主要就是排序,填充,而分查找等。注意:排序使用的是快速排序,时间复杂度是o(n*log(n))如果你要对数组排序,Arrays绝对是首选。
byte[] b1 = new byte[]{1, 2, 3};
int[] a = new int[]{1, 2, 3};
if (b1 instanceof Object) {
System.out.println("b1 instanceof Object!!");
System.out.println(b1.length); //b1作为一个对象,拥有length属性
System.out.println("class name=" + b1.getClass().getName());
System.out.println("class name=" + a.getClass().getName());
}
结果
b1 instanceof Object!!
3
class name=[B
class name=[I
参考:
http://blog.csdn.net/treeroot/article/details/264001
http://blog.csdn.net/fenglibing/article/details/17116601
http://stackoverflow.com/questions/1058149/using-a-byte-array-as-hashmap-key-java
http://www.cnblogs.com/batys/archive/2011/10/25/2223942.html
====END====