Java 检查哈希集中是否存在数组<;int[]>;
如何检查Java 检查哈希集中是否存在数组<;int[]>;,java,arrays,collections,contains,hashset,Java,Arrays,Collections,Contains,Hashset,如何检查哈希集中是否存在数组 例如: int[]a=新的int[]{0,0}; HashSet=newhashset(); 增加(a); 然后: int[]b=新的int[]{0,0}; 集合。包含(b);//=>真的 使用数组 包含?真的 然而,List方法有一个空间代价,因为它存储的是Integer对象,而不是int原语,这通常会占用更多空间 节省空间和时间:开发自定义类 如果上述方法仍然不够有效(大多数情况下都是如此),您可以使用自己的类来计算数字: public class IntAr
哈希集中是否存在数组
例如:
int[]a=新的int[]{0,0};
HashSet=newhashset();
增加(a);
然后:
int[]b=新的int[]{0,0};
集合。包含(b);//=>真的
使用数组
包含?真的
然而,List
方法有一个空间代价,因为它存储的是Integer
对象,而不是int
原语,这通常会占用更多空间
节省空间和时间:开发自定义类
如果上述方法仍然不够有效(大多数情况下都是如此),您可以使用自己的类来计算数字:
public class IntArray {
int[] elements;
public IntArray(int... elements) {
// Make a defensive copy to shield from subsequent modifications of the original array
this.elements = Arrays.copyOf(elements, elements.length);
}
@Override
public int hashCode() {
return Arrays.hashCode(elements);
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
IntArray other = (IntArray) obj;
return Arrays.equals(elements, other.elements);
}
}
这将允许:
IntArray a = new IntArray(0, 0);
HashSet<IntArray> set = new HashSet<>();
set.add(a);
IntArray b = new IntArray(0, 0);
System.out.println("Contains? " + set.contains(b));
(可能发生阵列突变或防御性阵列克隆),或
差不多
public final class Key<T> {
private final Predicate<T> equals;
private final IntSupplier hashCode;
public static Key<int[]> of(final int[] array) {
return new Key<>(that -> Arrays.equals(array, that), () -> Arrays.hashCode(array));
}
公共最终类密钥{
私有最终谓词等于;
私人最终供应商代码;
的公共静态密钥(最终int[]数组){
返回新键(that->Arrays.equals(array,that),()->Arrays.hashCode(array));
}
保持通用性
也许我能想到的另一个解决方案是使用
或
而不是
列表
(例如。
正确地覆盖等于
和hashCode
),不确定是否值得
现在添加所有可能的解决方案(可能还有更多?):
您可以使用而不是与比较器一起使用,比较器比较两个数组的内容,而不是两个数组对象的哈希代码。然后您可以使用如下方法:
int[]a={0,0};
int[]b={0,0};
int[]c={0,0};
HashSet HashSet=新的HashSet();
TreeSet TreeSet=新树集(数组::比较);
addAll(a,b,c的列表);
(a,b)的列表;
System.out.println(hashSet.size());//3
System.out.println(treeSet.size());//1
System.out.println(treeSet.contains(a));//true
System.out.println(treeSet.contains(b));//true
System.out.println(treeSet.contains(c));//true
为了完整性起见,值得添加一个自定义密钥类解决方案,因为创建这样一个密钥类实例在内存使用方面会更便宜(特别是对于不一定使用Integer
cache+中的int的大型基元数组,它适用于double[]
或char[]
),而且速度更快(特别是对于面向散列的大型集合,其中使用线性搜索是性能杀手).说得好,@fluffy,谢谢。如果你愿意,你可以在自己的答案中添加,或者我可以在我的答案中添加。现在我已经提到了空间惩罚,这是从你的评论中得到的启发。是的,如果你愿意,请添加它:一个涵盖大多数/所有情况的答案更好(在我看来)。此外,如果我没有记错的话,可以有两种基于密钥的解决方案:类似于公共最终类IntArrayKey{private final int[];…}
(可能会发生数组变异或防御性数组克隆),或者类似于公共最终类密钥的解决方案{private final Predicate equals;private final IntSupplier hashCode;public static Key of(final int[]array){返回新键(that->array.equals(array,that),()->Arrays.hashCode(array));}
以保持其通用性。我可能想到的另一个解决方案是使用或代替List
(例如,覆盖等于
和hashCode
正确)。现在不确定是否值得添加所有可能的解决方案(可能还有更多?):
IntArray a = new IntArray(0, 0);
HashSet<IntArray> set = new HashSet<>();
set.add(a);
IntArray b = new IntArray(0, 0);
System.out.println("Contains? " + set.contains(b));
public final class IntArrayKey {
private final int[];
...
}
public final class Key<T> {
private final Predicate<T> equals;
private final IntSupplier hashCode;
public static Key<int[]> of(final int[] array) {
return new Key<>(that -> Arrays.equals(array, that), () -> Arrays.hashCode(array));
}