在 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
,其中包含原始数组的所有元素(从 int
到 Integer
装箱)。
由于 LinkedHashSet
(与所有 Set
一样)不包含重复元素,当且仅当 Set
的大小等于数组的长度。
如果数组有任何重复项,Set
的大小会小于数组的长度,因为在 LinkedHashSet
初始化时重复项会被消除。
您发布的代码执行以下操作:
将 Integer[]
转换为 List<Integer>
。这样就可以很容易地从 List<Integer>
构造出 Set
对象。这是因为 LinkedHasSet
有一个构造函数,它接受另一个 Collection
类型并使用它的值构造一个集合。
将 List<Integer>
转换为 LinkedHashSet<Integer>
,当发生这种情况时,如果 List<Integer>
中有重复的 Integer
,因为列表可能有重复项, 这将在结果集中被消除。
现在在最后一步计算LinkedHashSet<Integer>
的大小,如果大小不等于原始数组seq
的length
那么它表示 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
数组中有重复项。
我在 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
,其中包含原始数组的所有元素(从 int
到 Integer
装箱)。
由于 LinkedHashSet
(与所有 Set
一样)不包含重复元素,当且仅当 Set
的大小等于数组的长度。
如果数组有任何重复项,Set
的大小会小于数组的长度,因为在 LinkedHashSet
初始化时重复项会被消除。
您发布的代码执行以下操作:
将
Integer[]
转换为List<Integer>
。这样就可以很容易地从List<Integer>
构造出Set
对象。这是因为LinkedHasSet
有一个构造函数,它接受另一个Collection
类型并使用它的值构造一个集合。将
List<Integer>
转换为LinkedHashSet<Integer>
,当发生这种情况时,如果List<Integer>
中有重复的Integer
,因为列表可能有重复项, 这将在结果集中被消除。现在在最后一步计算
LinkedHashSet<Integer>
的大小,如果大小不等于原始数组seq
的length
那么它表示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
数组中有重复项。