JAVA 8 通过引入 java.util.stream包 和 Lambda表达式实现了使用一行代码解决这个问题:
List<Person> beerDrinkers = persons.stream().filter(p -> p.getAge() > 16).collect(Collectors.toList());
使用 Collection.removeIf 在满足条件的情况下修改集合 。(注意:在本例中,将删除满足条件的对象):
persons.removeIf(p -> p.getAge() <= 16);
Lambdaj 库允许在不写循环或内部类的情况下过滤集合(Lambdaj允许以伪函数和静态类型的方式操作集合,在迭代集合时部分地消除写循环(通常是嵌套的和可读性差的)的负担):
List<Person> beerDrinkers = select(persons, having(on(Person.class).getAge(),greaterThan(16)));
【你知道筛选 Java 集合的最佳方法 吗?】你无法想象比这更容易理解的东西!
假设你使用的是 Java 1.5,并且你无法使用谷歌的 Collections,我会做一些与谷歌非常相似的事情 。
首先将下面的接口添加到你的代码中:
public interface IPredicate<T> { boolean Apply(T type); }
当判断为某种类型的真时,实现者可以进行返回 。例如:如果 T 是 User,并且AuthorizedUserPredicate <User>实现 IPredicate <T>,则
AuthorizedUserPredicate.apply返回传入的 User是否被授权 。
在一些通用的工具类中,可以这样写:
public static <T> Collection<T> filter(Collection<T> target, IPredicate<T> predicate) {Collection<T> result = new ArrayList<T>();for (T element: target) {if (predicate.apply(element)) {result.add(element);}}return result;}
所以,可能你会进行下面的实现:
Predicate<User> isAuthorized = new Predicate<User>() {public boolean apply(User user) {// binds a boolean method in User to a referencereturn user.isAuthorized();}};// allUsers is a Collection<User>Collection<User> authorizedUsers = filter(allUsers, isAuthorized);
如果关注线性检查的性能,那么我可能需要一个具有目标集合的域对象 。具有目标集合的域对象将具有用于初始化、添加和设置目标集合的方法的筛选逻辑 。
更新:
在工具类(就叫 Predicate吧)中,我添加了一个选择方法,其中包含一个在谓词不返回预期值时用于默认值的选项,以及一个用于在新 IPredicate 中使用的参数的静态属性
public class Predicate {public static Object predicateParams;public static <T> Collection<T> filter(Collection<T> target, IPredicate<T> predicate) {Collection<T> result = new ArrayList<T>();for (T element : target) {if (predicate.apply(element)) {result.add(element);}}return result;}public static <T> T select(Collection<T> target, IPredicate<T> predicate) {T result = null;for (T element : target) {if (!predicate.apply(element))continue;result = element;break;}return result;}public static <T> T select(Collection<T> target, IPredicate<T> predicate, T defaultValue) {T result = defaultValue;for (T element : target) {if (!predicate.apply(element))continue;result = element;break;}return result;}}
下面的示例展示了如何在集合之间查找丢失的对象:
List<MyTypeA> missingObjects = (List<MyTypeA>) Predicate.filter(myCollectionOfA,new IPredicate<MyTypeA>() {public boolean apply(MyTypeA objectOfA) {Predicate.predicateParams = objectOfA.getName();return Predicate.select(myCollectionB, new IPredicate<MyTypeB>() {public boolean apply(MyTypeB objectOfB) {return objectOfB.getName().equals(Predicate.predicateParams.toString());}}) == null;}});
下面的示例展示了在集合中查找实例,并在没有找到实例时将集合的第一个元素作为默认值返回:
MyType myObject = Predicate.select(collectionOfMyType, new IPredicate<MyType>() {public boolean apply(MyType objectOfMyType) {return objectOfMyType.isDefault();}}, collectionOfMyType.get(0));
更新 (Java 8 发布后):final UserService userService = ... // perhaps injected IoCfinal Optional<UserModel> userOption = userCollection.stream().filter(u -> {boolean isAuthorized = userService.isAuthorized(u);return isAuthorized;}).findFirst();
可选的 JDK 8 API 具有 get(),isPresent(),orElse(defaultUser),orElseGet(userSupplier)和 orElseThrow(exceptionSupplier) 以及其他单一的方法,例如:map, flatMap和 filter 。
如果你只想筛选满足条件的所有用户,请使用收集器将流终止于所需的收集中:
final UserService userService = ... // perhaps injected IoCfinal List<UserModel> userOption = userCollection.stream().filter(u -> {boolean isAuthorized = userService.isAuthorized(u);return isAuthorized;}).collect(Collectors.toList());
推荐阅读
- 翡翠|高档翡翠的极简主义设计,这篇文章告诉你
- 便秘|女人早上起床之后,若身体没有这些表现,或许你会越来越瘦
- 四个方法助你缓解打呼噜 什么偏方治打呼噜
- hr|想致富,转思路:适合普通人的3个“生财之路”,助你告别贫穷
- 混动车|五菱:你见过像电车的混动吗?三电核心系统揭秘
- 6妙招助你去除头皮屑 头皮屑多又痒怎么办
- 少数民族的传统节日你知多少 少数民族的传统节日
- 动物|切勿“圣母心泛滥”:掉在路边的幼鸟其实并不需要你救助
- 微信怎么知道对方是否在线
- 五种方法缓解帮你缓解情绪 心烦怎么办