Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/377.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java字节数组集_Java_Set - Fatal编程技术网

Java字节数组集

Java字节数组集,java,set,Java,Set,我有一个byte[]s的散列集,我想测试一个新的byte[]是否在该集中。问题在于Java似乎在测试byte[]实例是否相同,而不是测试字节数组中的实际值是否相同 换句话说,考虑下面的代码: public class Test { public static void main(String[] args) { java.util.HashSet<byte[]> set=new java.util.HashSet<byte[]>();

我有一个
byte[]
s的散列集,我想测试一个新的
byte[]
是否在该集中。问题在于Java似乎在测试
byte[]
实例是否相同,而不是测试字节数组中的实际值是否相同

换句话说,考虑下面的代码:

public class Test
{
    public static void main(String[] args)
    {
        java.util.HashSet<byte[]> set=new java.util.HashSet<byte[]>();
        set.add(new String("abc").getBytes());
        System.out.println(set.contains(new String("abc").getBytes()));
    }
}
公共类测试
{
公共静态void main(字符串[]args)
{
java.util.HashSet=new java.util.HashSet();
添加(新字符串(“abc”).getBytes());
System.out.println(set.contains(新字符串(“abc”).getBytes());
}
}

此代码打印出
false
,我希望它打印出
true
。我应该怎么做呢?

您可以定义自己的包装器类,但最简单的方法可能是将数组“包装”到ArrayList中,并使用
哈希集

您可以创建一个
ByteArray
类,以您想要的方式包装字节数组并测试是否相等。然后您就有了一个
集合

您可以使用
ByteBuffer.wrap来包装每个字节数组,这将为您提供正确的equals和hashCode行为。只需小心调用
ByteBuffer
(不要修改数组或推进其指针)的方法。

您可以避免包装器和愚蠢的哈希代码问题(嘿,像byte[]这样的标准对象没有正确的哈希代码?)

使用TreeSet而不是HashSet,并在实例化时提供byte[]比较器:

  Set<byte[]> byteATreeSet = new TreeSet<byte[]>(new Comparator<byte[]>() {
    public int compare(byte[] left, byte[] right) {
    for (int i = 0, j = 0; i < left.length && j < right.length; i++, j++) {
        int a = (left[i] & 0xff);
        int b = (right[j] & 0xff);
        if (a != b) {
            return a - b;
        }
    }
    return left.length - right.length;
   }});
Set byteATreeSet=新树集(新比较器(){
公共整数比较(字节[]左,字节[]右){
对于(int i=0,j=0;i
如果您从其他地方获得字节[]哈希集b,请在之前将变量a初始化为TreeSet,然后使用a.addAll(b);这样,即使b包含重复项,a也不会。

Modern(从现在的解决方案开始)
import com.google.common.collect.ImmutableSet;
导入java.nio.ByteBuffer;
导入java.util.Set;
导入静态com.google.common.base.Charsets.UTF_8;
导入静态java.nio.ByteBuffer.wrap;
公共课刮刮
{
公共静态void main(字符串[]args)
{
最终设置bbs=ImmutableSet.of(wrap(“abc”.getBytes(UTF_8)).asReadOnlyBuffer());
System.out.println(“bbs.contains(ByteBuffer.wrap(\“abc\”.getBytes(Charsets.UTF_8)))=”+bbs.contains(wrap(“abc.getBytes(UTF_8)).asReadOnlyBuffer());
}
}
笔记: 在不提供
字符集的情况下,决不能将
字符串
转换为
字节[]
。结果取决于默认的
字符集
,默认的
字符集通常不是好的,可以更改

.asReadOnlyBuffer()
很重要

创建一个新的只读字节缓冲区,该缓冲区共享此缓冲区的 内容。新缓冲区的内容将是此缓冲区的内容。 对该缓冲区内容的更改将在新缓冲区中可见; 但是,新缓冲区本身将是只读的,不允许 要修改的共享内容

两个缓冲器的位置、极限和标记值将是独立的

新缓冲区的容量、限制、位置和标记值将与此缓冲区的相同。 如果此缓冲区本身是只读的,则此方法的行为完全相同 与复制方法相同


在所有这些答案中,要小心更改集合中字节数组的任何元素;这样做将影响其哈希及其相等性,但不会更改其当前存储的哈希桶。值得注意的是,TreeSet的添加、删除、包含方法的时间复杂度比HashSet(O(lg n)vs O(1))差,这可能是一个重要因素。
import com.google.common.collect.ImmutableSet;

import java.nio.ByteBuffer;
import java.util.Set;

import static com.google.common.base.Charsets.UTF_8;
import static java.nio.ByteBuffer.wrap;

public class Scratch
{
    public static void main(String[] args)
    {
        final Set<ByteBuffer> bbs = ImmutableSet.of(wrap("abc".getBytes(UTF_8)).asReadOnlyBuffer());
        System.out.println("bbs.contains(ByteBuffer.wrap(\"abc\".getBytes(Charsets.UTF_8))) = " + bbs.contains(wrap("abc".getBytes(UTF_8)).asReadOnlyBuffer()));
    }
}