我真的不知道如何制定这个问题的标题,所以我只是跳到一个例子中。
让我们说我想迭代一个元素列表,并根据某些条件,将所述元素添加到一个新列表中。
这里我创建了一个方法,基本上想要检查一个项是否是第一个列表的独占(第二个列表中不存在)。现在我知道,对于这个特别愚蠢的例子,你可以用套装来解决这个问题,但我只是想说明一个像这样的东西弹出的情况
public List<Item> newItems(List<Item> items, List<Item> otherItems) {
List<Item> newItems = new ArrayList<>();
for (Item i: items) {
for (Item j: otherItems) {
if (i.equals(j))
//Missing code
}
newItems.add(i);
}
return newItems;
}
所以在这里我只想将Item i
添加到newItems
,如果它不等于otherItems
中的单个项目。我的第一个冲动是将break;
放在//Missing Code
所在的位置,但这只会突破第一个循环而不会妨碍i
添加到newItems
。
我知道一个正确的解决方案,你可以使用布尔变量来一致地检查if语句的真实性,然后根据它的真值将Item i
添加到newItems
在第二个循环结束时。它看起来像这样:
for (Item i: items) {
boolean check = true;
for (Item j: otherItems) {
if (i.equals(j))
check = false;
break; //To avoid unnecessary iterations
}
if (check)
newItems.add(i);
}
这看起来非常笨重,但也非常多余。有没有更有效和更优雅的方式来做到这一点?
答案 0 :(得分:3)
如果我正确理解了您的问题,您需要创建一个列表,其中收集的项目来自t\d*.+?x\d*.([a-z]\d.){1,6}
,不包括items
和items
中的项目。如果是,您只需List#removeAll()
:
otherItems
如果还有其他条件要排除项目,请使用流,过滤器和收集器,如下所示:
public List<Item> newItems(List<Item> items, List<Item> otherItems) {
List<Item> res = new ArrayList<>(items); // create a copy of items
res.removeAll(otherItems); // remove items presented in otherItems
return res;
}
答案 1 :(得分:2)
正如Wakachopo和AchmadJP指出的那样,您可以使用contains
或binarySearch
执行您所描述的内容。现在您说,这些操作只是示例性的,您可能有不同的条件 - 没有什么能阻止您使用相同的模式,但现在您可能必须自己编写特定的方法:
for(Item i: items) {
if(!hasMatchingCondition(i, otherItems) {
newItems.add(i);
}
}
static boolean hasMatchingCondition(Item i, List<Item> list) {
for(Item j: list) {
if(whatever condition regarding i and j) {
return true;
}
}
return false;
}
清洁和短路。
您可以使用标记语句在单一方法中执行相同操作,即
outer: for(Item i: items) {
for(Item j: list) {
if(whatever condition regarding i and j) {
continue outer;
}
}
newItems.add(i);
}
但是一些开发人员认为标记语句是一种沮丧的功能,也许更重要的是,您可能会在某处找到hasMatchingCondition
方法的另一种用途。
答案 2 :(得分:1)
嗯,如果List已经排序了。我认为更快的解决方案是使用二进制搜索,因为它比顺序搜索更快。
for( Item i: items){
if(Collections.binarySearch(otherItems, i) < 0){
newItems.add(i);
}
}
答案 3 :(得分:1)
如果必须,我会这样做:
for(Item i: items){
if(!otherItems.contains(i)){
newItems.add(i);
}
}
答案 4 :(得分:1)
在这个和其他情况下,我认为你可以给他们一个颠倒的焦点,并假设所有项目都符合你的条件,然后删除那些没有。对于这个例子:
{{1}}
答案 5 :(得分:1)
作为嵌套循环的替代方法,在Java 8中,您可以使用Streams API执行以下操作:
public List<Item> newItems(List<Item> items, List<Item> otherItems) {
return items.stream()
.filter(i -> !otherItems.contains(i))
.collect(Collectors.toList());
}
答案 6 :(得分:0)
嗯,你可以这样做;
CollectionUtils.removeAll(collection1, collections2);
此方法也会向您返回一个集合。