byte[]作为key存储在HashSet中

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

转载于:https://my.oschina.net/xinxingegeya/blog/286309

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值