在 Java 中使用 LinkedHashSet 检查数组中的唯一值

Checking unique values in array using LinkedHashSet in Java

我在 HackerRank 上看到这段代码,理解这段代码时我真的很困惑,它 使用 HashMap[=38= 检查数组中元素的唯一性].

现在给大家科普一下,我知道怎么做,而且也很简单。但是这段代码是不同的,我真的需要了解它的实际作用和作用。

int[] seq = new int[]{3,2,1,3};

Integer[] tmp = new Integer[seq.length];
for (int i = 0; i < seq.length; ++i) {
  tmp[i] = Integer.valueOf(seq[i]);
}

/* THIS PIECE OF CODE, HOW THIS WORKS AND WHAT IT DOES???*/         
if (!((new LinkedHashSet<Integer>(Arrays.asList(tmp))).size() == seq.length)) {
    throw new AssertionError("not all values are unique");
}

我能弄清楚的是它将数组转换为 tmp

的列表
Arrays.asList(tmp)

2. 将其转换为 LinkedHashSet

LinkedHashSet<Integer>(Arrays.asList(tmp))

3.然后求HashSet的大小

(LinkedHashSet<Integer>(Arrays.asList(tmp))).size()

4. 与数组seq的长度进行比较。

(new LinkedHashSet<Integer>(Arrays.asList(tmp))).size() == seq.length)

如果长度不等于数组seq那元素怎么是唯一的?

此代码创建一个 LinkedHashSet,其中包含原始数组的所有元素(从 intInteger 装箱)。

由于 LinkedHashSet(与所有 Set 一样)不包含重复元素,当且仅当 Set 的大小等于数组的长度。

如果数组有任何重复项,Set 的大小会小于数组的长度,因为在 LinkedHashSet 初始化时重复项会被消除。

您发布的代码执行以下操作:

  1. Integer[] 转换为 List<Integer>。这样就可以很容易地从 List<Integer> 构造出 Set 对象。这是因为 LinkedHasSet 有一个构造函数,它接受另一个 Collection 类型并使用它的值构造一个集合。

  2. List<Integer> 转换为 LinkedHashSet<Integer>,当发生这种情况时,如果 List<Integer> 中有重复的 Integer,因为列表可能有重复项, 这将在结果集中被消除。

  3. 现在在最后一步计算LinkedHashSet<Integer>的大小,如果大小不等于原始数组seqlength那么它表示 LinkedHashSet<Integer> 中的某些元素重复并在转换时被删除。

QUESTION: And if the length is not equal to the array seq, then how come the elements are unique?

这是因为如果结果 LinkedHashSet<Integer> 与初始 Integer[] 相比具有更少的元素,则意味着消除了重复对象。如果它们相等,则意味着没有对象被消除并且所有对象都是唯一的。

如果您想用更少的代码行进行检查,您可以使用 Streams API:

int[] seq = new int[]{3,2,1,3};
System.out.println(String.format("Array has duplicates: %b", 
                   Arrays.stream(seq).distinct().count() != seq.length));

这会给你 Array has duplicates: true 因为它在 seq 数组中有重复项。