英文:
Is there a widely used util/library method in Java to tell if all elements in a collection are unique?
问题
I'm looking for a method that, if it were in the standard library, would probably be something like boolean Collections#areAllUnique(Collection)
. 我正在寻找一种方法,如果它在标准库中,可能会类似于 boolean Collections#areAllUnique(Collection)
。
I want a method that returns true iff there are no duplicates in the collection. 我想要一个方法,当集合中没有重复项时返回 true。
Obviously, this would return true for any (properly implemented) Set. 显然,对于任何(正确实现的)Set,这将返回 true。
It's also easy to write yourself, as something like collection.size() == new HashSet(collection).size()
. However, there are a few reasons I'd still like to see it as a one-line library method: 你也可以很容易地自己编写,类似于 collection.size() == new HashSet(collection).size()
。然而,还有一些原因,我仍然希望将其作为一行库方法:
-
It's easier 1)这更容易
-
The above is not as efficient as it could be; the method could avoid building the entire second set if it detects any duplicates. 2)上述方法不如可能的效率高;如果检测到任何重复项,该方法可以避免构建整个第二个集合。
A good implementation might look like 一个良好的实现可能如下所示:
public static <T> boolean areAllUnique(Collection<T> collection) {
if (collection instanceof Set) {
return true;
}
HashSet<T> set = new HashSet<>(collection.size());
for (T t : collection) {
if (set.contains(t)) {
return false;
}
set.add(t);
}
return true;
}
Is there a method like this somewhere in the Java standard library or any of the well-known libraries out there (Guava, etc.)? 在Java标准库或其他知名库中是否有类似这样的方法(例如Guava等)?
英文:
I'm looking for a method that, if it were in the standard library, would probably be something like boolean Collections#areAllUnique(Collection)
. I want a method that returns true iff there are no duplicates in the collection.
Obviously, this would return true for any (properly implemented) Set.
It's also easy to write yourself, as something like collection.size() == new HashSet(collection).size()
. However, there are a few reasons I'd still like to see it as a one-line library method:
- It's easier
- The above is not as efficient as it could be; the method could avoid building the entire second set if it detects any duplicates.
A good implementation might look like
public static <T> boolean areAllUnique(Collection<T> collection) {
if (collection instanceof Set) {
return true;
}
HashSet<T> set = new HashSet<>(collection.size());
for (T t : collection) {
if (set.contains(t)) {
return false;
}
set.add(t);
}
return true;
}
Is there a method like this somewhere in the Java standard library or any of the well-known libraries out there (Guava, etc.)?
答案1
得分: 2
我相当确信Guava中不存在这样的方法。
您的方法基本上是正确的;我会对其进行一些微调,以使其稍微更清晰/更高效:
// T并不真正起作用。通配符就足够了。
public static boolean areAllUnique(Collection<?> collection) {
if (collection instanceof Set) {
return true;
}
HashSet<Object> set = new HashSet<>(collection.size());
for (Object t : collection) {
// add只在集合发生变化时返回true,因此您不需要分开进行contains/add操作。
if (!set.add(t)) {
return false;
}
}
return true;
}
如果您想让API设计者感到沮丧(因为谓词应该是无状态的),您还可以更简洁地执行相同的操作:
return collection instanceof Set
|| collection.stream().allMatch(new HashSet<>(collection.size())::add);
英文:
I'm pretty sure that no such method exists in Guava.
Your method is mostly fine; I would make a couple of tweaks to it to make it marginally cleaner/more efficient:
// T doesn't really do anything. A wildcard is sufficient.
public static boolean areAllUnique(Collection<?> collection) {
if (collection instanceof Set) {
return true;
}
HashSet<Object> set = new HashSet<>(collection.size());
for (Object t : collection) {
// add only returns true if the set is changed, so you don't need to
// do contains/add separately.
if (!set.add(t)) {
return false;
}
}
return true;
}
If you want to make the API designers cry (because predicates should be stateless), you can also do the same thing more concisely:
return collection instanceof Set
|| collection.stream().allMatch(new HashSet<>(collection.size())::add);
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论