在Java中过滤集合中的元素的简单方法?
我想编写一个方法,从集合中删除遵循特定模式的所有元素。在函数式语言中,我会将 filter() 与 lambda 表达式结合使用。然而,在Java中,我似乎陷入了困境:
public void removeAllBlueCars() {
LinkedList<Car> carsToRemove = new LinkedList<Car>();
for (Car c : cars) {
if (c.getCarColor() == Color.BLUE) {
carsToRemove.add(c);
}
}
cars.removeAll(carsToRemove );
}
删除元素直接导致ConcurrentModificationException。有没有更好的方法可以在不借助 Google 收藏集的情况下实现此目的?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(12)
对于那些遇到这个线程并且可能正在使用 RxJava/RxAndroid 处理 Android 的人来说,有一种快速方法可以做到这一点,而无需添加 Apache Commons Collections 依赖项:
请注意,我也碰巧在 Retrolambda。如果您不使用 Retrolambda,您可以使用以下内容表达相同的内容:
For those of you who come across this thread and might be working on Android with RxJava/RxAndroid, there's a quick way to do this without adding the Apache Commons Collections dependency:
Note that I also happen to be using lambda expressions with Retrolambda. If you aren't using Retrolambda, you can express the same thing using the following:
随着Java8引入lambda表达式,实现过滤变得更加容易以更实用的方式构建集合。
我给你写了一个例子。另请注意使用 forEach 打印 Collection 内容是多么的好:
With Java8 introducing lambda expressions, it's much easier to implement filtering on a collection in a more functional approach.
I wrote an example for you. Please also note how nicer it is to print Collection content using forEach:
将某种泛型类型的列表传递给此函数,并使用谓词删除不需要的元素。
Pass a list of some generic type to this function with a predicate to remove unwanted elements.
这确实是一篇旧文章,但是如何使用 Oracle Java 教程中给出的方法。
It's really an old post but how abt using the way given in Oracle Java tutorial.
我非常喜欢 Vivien Barousse 和 gpeche 提供的迭代器解决方案。但我想指出的是,您不必实际从集合中删除任何元素,只需防止过滤器返回它们即可。这样,您基本上就可以拥有同一集合的多个视图,这非常方便和高效。 Filter 对象基本上是您的 lamda 表达式,或者与 Java 版本 7 之前的最接近的表达式...
I'm a big fan of the Iterator solution provided by Vivien Barousse and gpeche. But I wanted to point out that you don't have to actually remove any elements from the collection, you just need to prevent the filter from returning them. That way, you basically have multiple views of the same collection, which can be very convenient and efficient. The Filter object is basically your lamda expression, or as close as you're gonna get in Java until version 7...
您总是可以向后退并删除元素。
编辑:注意到它是一个 LinkedList,这可能使我的答案有点不相关。
You could always go backwards and delete the elements..
edit: Noticed it was a LinkedList which might make my answer a bit non-relevant.
了解 lambdaj 的过滤选项是否可以为您提供帮助。
See if lambdaj's filter option can help you.
以下是 Android 实现通用解决方案的方法:
用法:
从我的列表中删除所有空字符串
来源:
Here is the Android way to implement a generic solution for this:
Usage:
Remove all null strings from my list
Source:
您可以使用 CollectionUtils.filter()。它与
Iterator
配合使用,因此直接从Collection
中删除项目应该没有问题。但这是另一种依赖。如果你想要独立的代码,那就是:You can use CollectionUtils.filter(). It works with an
Iterator
, so it should have no problems removing items directly from theCollection
. It is another dependency though. If you want the code standalone it would be:您可以使用
ListIterator
,它有一个 删除 方法。顺便说一句,您应该将列表声明为
List
- 接口程序,而不是实现程序。You could iterate through the list using a
ListIterator
, which has a remove method.Btw you should declare your list as
List<Car>
- program for interfaces, not implementation.也许你可以使用迭代器,它的效率更高一些:
另外,如果你想让这个解决方案更通用,我建议你这样做:
你可以这样使用它:
你的方法被这样调用:
Maybe you could use iterators, which are a little more efficient:
Also, if you want to make this solution more generic, I'd suggest you something like:
And you could use it like this:
Your method gets called like this:
使用 Java 8,您可以使用
Collection.removeIf
。With Java 8, you can filter with a lambda expression using
Collection.removeIf
.