[英]How equals 3 ArrayList<String> and check matches of objects in this lists?
我有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;
如果更容易
我認為您已經找到了將三個列表添加到集合中的想法。 這是一個等效的通用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();
}
}
使用三組而不是列表。 這有幾個優點:
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());
效率和優雅的完美結合可能是:
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");
告訴您哪些項目已重復。
找到第一個重復項后,這兩個版本的代碼都將引發異常。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.