Java 如何等于3 ArrayList<;字符串>;并检查此列表中对象的匹配情况?
我有3个字符串列表Java 如何等于3 ArrayList<;字符串>;并检查此列表中对象的匹配情况?,java,list,arraylist,collections,Java,List,Arraylist,Collections,我有3个字符串列表 private @Getter @Setter List<String> allowedServicesId; private @Getter @Setter List<String> notAllowedServicesId; private @Getter @Setter List<String> replaceServiceId; 但我认为这是一种坏习惯。我想还有另一种方法 编辑 我想出来了 Set<String> se
private @Getter @Setter List<String> allowedServicesId;
private @Getter @Setter List<String> notAllowedServicesId;
private @Getter @Setter List<String> replaceServiceId;
但我认为这是一种坏习惯。我想还有另一种方法
编辑
我想出来了
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("");
}
如果更简单的话我想你已经找到了一个可以接受的答案,可以将三个列表添加到一个集合中。下面是一个等效的、更通用的Java8代码
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();
}
}
private static void assertForDuplicates(集合…集合)引发异常{
int n=0;
用于(集合c:集合){
n+=c.尺寸();
}
if(Stream.of(collections).flatMap(Collection::Stream).Collection(Collectors.toSet()).size()!=n){
抛出新异常();
}
}
使用三个集合而不是列表。这有几个优点:
- 由于每个集合都不应包含重复的元素,因此使用
(不允许此类重复元素共存)既清晰又可以避免潜在的错误Set
- 集合操作(添加、包含等)比列表操作效率更高。特别是,在列表中查找元素是O(|列表的大小|),在
哈希集中查找元素是O(1)
字符串集合中重复项的有效方法:
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;
}
这允许您保留一套:
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());
地图服务byid;
服务httpService=servicesbyd.get(“http”);
System.out.println(“服务http的状态为”+httpService.getStatus());
效率与优雅的完美结合可能是:
Set<String> set = new HashSet<>();
if (Stream.of(allowedServicesId, notAllowedServicesId, replaceServiceId)
.flatMap(List::stream).anyMatch(s -> !set.add(s)))
throw new Exception();
Set Set=newhashset();
if(Stream.of(allowedServicesId、notAllowedServicesId、replaceServiceId)
.flatMap(List::stream).anyMatch(s->!set.add(s)))
抛出新异常();
或更有用:
Optional<String> dupe = Stream.of(allowedServicesId, notAllowedServicesId, replaceServiceId)
.flatMap(List::stream)
.filter(s -> !set.add(s))
.findFirst();
if (dupe.isPresent())
throw new Exception(dupe + " was duplicated");
Optional dupe=Stream.of(allowedServicesId、notAllowedServicesId、replaceServiceId)
.flatMap(列表::流)
.filter->!set.add(s))
.findFirst();
if(dupe.isPresent())
抛出新异常(dupe+“已复制”);
这会告诉你哪个项目是重复的
两个版本的代码都会在找到第一个副本后立即抛出异常。是的。。。在你的循环中有一个循环,检查两次相同的东西。这真的没有必要。ô…@Ephi它并没有解决问题,它只是让代码变得更短。问题是,如果你有10个数组呢?伙计,我无法想象……您的代码是否允许重复?如果一个列表包含两次相同的IDI,您设置的代码将失败。您似乎保留了3个或多个列表,以维护您的服务的独占属性(例如,一个服务可以是允许的
或替换的
或不允许的
)。您应该通过定义服务
类将这些属性放在服务本身中。但是,这可能会很慢。假设您在前两个元素中检测到重复。为什么要一直抱怨到最后呢?@tucuxi你说得对。就性能而言,我的解决方案远不是最优的。我认为(尽管我不是OP),第二种方法超出了OP问题的范围,这正是我们可以从高质量的答案中期待的。
Map<String, Service> servicesById;
Service httpService = servicesById.get("http");
System.out.println("The status of service http is " + httpService.getStatus());
Set<String> set = new HashSet<>();
if (Stream.of(allowedServicesId, notAllowedServicesId, replaceServiceId)
.flatMap(List::stream).anyMatch(s -> !set.add(s)))
throw new Exception();
Optional<String> dupe = Stream.of(allowedServicesId, notAllowedServicesId, replaceServiceId)
.flatMap(List::stream)
.filter(s -> !set.add(s))
.findFirst();
if (dupe.isPresent())
throw new Exception(dupe + " was duplicated");