Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/326.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何等于3 ArrayList<;字符串>;并检查此列表中对象的匹配情况?_Java_List_Arraylist_Collections - Fatal编程技术网

Java 如何等于3 ArrayList<;字符串>;并检查此列表中对象的匹配情况?

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

我有3个字符串列表

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");