在 Set 中存储数组并避免重复

2022-09-01 04:10:24
HashSet<String[]> boog = new HashSet<String[]>();
boog.add(new String[]{"a", "b", "c"});
boog.add(new String[]{"a", "b", "c"});
boog.add(new String[]{"a", "b", "d"});

结果

[a, b, c]
[a, b, d]
[a, b, c]

其中重复,因此哈希函数未按预期工作。我将如何重写字符串数组的哈希方法。或者就此而言,一个通用数组?有没有更好的方法来完成我想做的事情?[a,b,c]


答案 1

你不能。数组使用默认的基于身份的 Object.hashCode() 实现,并且无法覆盖它。不要使用数组作为哈希映射/哈希集中的键!

请改用一组列表。


答案 2

“更好的方法”是使用集合。使用 代替 :ListString[]

Set<List<String>> boog = //...
boog.add(Arrays.asList("a", "b", "c"));
boog.add(Arrays.asList("a", "b", "c"));
boog.add(Arrays.asList("a", "b", "d"));

System.out.println(boog.size()); // 2

编辑

如果你绝对需要使用数组作为键,你可以在每个键周围构建一个透明的包装器,并将其放在映射中。一些库可以帮助您做到这一点。例如,以下是使用Trove的方法Set<String[]>

Set<String[]> boog = new TCustomHashSet<String[]>(new ArrayHashingStrategy());

boog.add(new String[]{"a", "b", "c"});
boog.add(new String[]{"a", "b", "c"});
boog.add(new String[]{"a", "b", "d"});

System.out.println(boog.size()); // 2

//...
public class ArrayHashingStrategy extends HashingStrategy<Object[]> {

   public int computeHashCode(Object[] array) {
      return Arrays.hashCode(array);
   }

   public boolean equals(Object[] arr1, Object[] arr2) {
      return Arrays.equals(arr1, arr2);
   }
}