从列表中删除包含字符串的对象 - 比较列表

3
我的问题是 - 如何通过与第二个列表进行比较来从列表中删除对象。
List1 - 第一个列表包含电子邮件地址。 List2 - 第二个列表仅包含格式为“@domain.com”等的域名。
我想要从第一个列表中删除包含第二个列表中的域名的对象(电子邮件)。
例如: 如果List1包含电子邮件地址:“email@domain.com”,而第二个List2包含“@domain.com” - 那么我想要删除此电子邮件(从List1中)。
我尝试使用:
List1.removeIf(s -> s.equals (List2));
List1.removeAll(List2);

很遗憾,它没有按我所希望的方式过滤我的列表。
我将非常感谢您的快速帮助。

1
字符串“someone@domain.com”不可能等于域名列表。它们甚至不是相同的类型。你需要学习更多基础知识,比如什么是相等。你想要做的是从电子邮件地址中提取域名(即将字符串“someone@domain.com”转换为字符串“domain.com”,然后检查域名列表是否包含结果(即包含“domain.com”)。 - JB Nizet
3个回答

5

类似于以下内容

list1.removeIf(email -> list2.stream().anyMatch(email::endsWith));

应该可以工作


3
首先,使用你的域名创建一个HashSet:
Set<String> domains = new HashSet<>(list2);

现在,在第一个列表中使用removeIf

list1.removeIf(email -> domains.contains("@" + email.split("@")[1]));

使用Set(而不是原始的list2)的想法是为了优化搜索,即使containsO(1)摊销时间内运行。 注意:我假设list2中的所有域都以"@"开头。

2
由于域名不区分大小写,而您的列表可能包含混合大小写,因此您可能希望确保列表2中的所有域名都是小写的,然后执行 domains.contains("@" + email.split("@")[1].toLowerCase()) - DodgyCodeException
2
另外,split使用正则表达式,这可能会占用大量的CPU时间。一种更有效的方法可能是domains.contains(email.substring(email.indexOf('@').toLowerCase())) - DodgyCodeException

2
你可以创建一个新的对象列表来从第一个列表中删除它们:
List<String> objectsToBeRemoved = list1.stream()
                                        .filer(email-> isNotValidEmail(email,list2))
                                        .collect(toList());
list1.removeAll(objectsToBeRemoved);

另一个选项是使用removeIf:
    List<String> emails = new ArrayList<>(Arrays.asList("email@domain.com", "email2@domain.com","ssss@ff.com"));
    List<String> domains = new ArrayList<>(Arrays.asList("@domain.com"));
    emails.removeIf(email -> isNotValidEmail(domains, email));

private boolean isNotValidEmail(List<String> domains, String email) {
    return domains.stream()
            .anyMatch(email::endsWith);
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接