byte[]做爲key存儲在HashSet中

hashCode和equals方法

當使用ide進行開發時,最簡單的重寫就是用ide自動生成hashCode和equals方法html

例如:java

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主要用在集合中進行對象的存取)ide

Java對於eqauls方法和hashCode方法是這樣規定的: 測試

一、若是兩個對象相同,那麼它們的hashCode值必定要相同;ui

二、若是兩個對象的hashCode相同,它們並不必定相同     this

上面說的對象相同指的是用eqauls方法比較。  ‍‍ spa

/**
 * 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數組

直接看代碼.net

@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
}

運行結果:code

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====

相關文章
相關標籤/搜索