我有3个字符串列表
private @Getter @Setter List<String> allowedServicesId;
private @Getter @Setter List<String> notAllowedServicesId;
private @Getter @Setter List<String> replaceServiceId;
我需要检查这些列表中是否至少有一个对象的交叉点?
我创建了这个
for (String s : allowedServicesId) {
if (notAllowedServicesId.contains(s)){
throw new Exception("");
}
if (replaceServiceId.contains(s)){
throw new Exception("");
}
}
for (String s : notAllowedServicesId) {
if (replaceServiceId.contains(s)){
throw new Exception("");
}
}
但我认为这是不好的做法。我认为还有另一种方式。
修改
我想通了
Set<String> set = new HashSet<>();
set.addAll(allowedServicesId);
set.addAll(notAllowedServicesId);
set.addAll(replaceServiceId);
int i = allowedServicesId.size() + notAllowedServicesId.size() + replaceServiceId.size();
if (set.size()!= i){
throw new Exception("");
}
和你一样?
修改
我可以将List
更改为Set
private @Getter @Setter Set<String> allowedServicesId;
private @Getter @Setter Set<String> notAllowedServicesId;
private @Getter @Setter Set<String> replaceServiceId;
如果更容易
答案 0 :(得分:2)
我认为您已经找到了一个可接受的答案,即将三个列表添加到集合中。这是一个等效且更通用的Java 8代码
private static void assertForDuplicates(Collection<?>... collections) throws Exception {
int n = 0;
for (Collection<?> c : collections) {
n += c.size();
}
if (Stream.of(collections).flatMap(Collection::stream).collect(Collectors.toSet()).size() != n) {
throw new Exception();
}
}
答案 1 :(得分:1)
使用三组而不是列表。这有几个好处:
Set
(不允许此类重复元素共存)更加清晰,可以避免潜在的错误。HashSet
中的O(1)。假设您正在使用集合,以下代码是测试String
集合中重复项的有效方法:
private boolean hasDuplicates(Set<String> ... sets) {
if (sets.size() < 2) return false; // no possible duplicates
Set<String> all = Hashnew Set<>();
for (Set<String> set : sets) {
for (String s : set) {
// adding to a set returns false if element was already there
if ( ! all.add(s)) return true;
}
}
return false;
}
一旦找到第一个副本,就会失败(并且可以轻松修改以报告匹配发生的位置)。在更糟糕的情况下,它等同于您的代码添加所有元素,然后测试以查看总大小是否符合预期。
修改 - 采取不同的行动
您似乎使用多个哈希集来保留服务的独占布尔属性。请考虑改为创建Service
类:
public class Service {
public enum Status { ALLOWED, REPLACE, NOT_ALLOWED };
private String id;
private Status status;
// constructors, getters & setters here
public int hashCode () { return id.hashCode(); }
public boolean equals(Object o) {
return o instanceof Service && id.equals(((Service)o).getId());
}
}
这允许您保留一组:
Set<Service> services; // guaranteed: each has exactly one status
更好的是,您可以使用地图通过其ID有效地检索服务:
Map<String, Service> servicesById;
Service httpService = servicesById.get("http");
System.out.println("The status of service http is " + httpService.getStatus());
答案 2 :(得分:0)
效率和优雅的良好结合可能是:
.st
或更有用:
Set<String> set = new HashSet<>();
if (Stream.of(allowedServicesId, notAllowedServicesId, replaceServiceId)
.flatMap(List::stream).anyMatch(s -> !set.add(s)))
throw new Exception();
告诉你哪个项目是重复的。
一旦找到第一个副本,两个版本的代码都会抛出异常。