我想根据谓词筛选java.util.Collection。


当前回答

考虑使用支持泛型的更新的Collections框架谷歌Collections。

更新:谷歌集合库现在已弃用。你应该使用最新发布的番石榴。它仍然具有对集合框架的所有相同扩展,包括基于谓词进行筛选的机制。

其他回答

我需要根据列表中已经存在的值来筛选列表。例如,删除后面小于当前值的所有值。{2 5 3 4 7 5} ->{2 5 7}。或者例如删除所有重复项{3 5 4 2 3 5 6}->{3 5 4 2 6}。

public class Filter {
    public static <T> void List(List<T> list, Chooser<T> chooser) {
        List<Integer> toBeRemoved = new ArrayList<>();
        leftloop:
        for (int right = 1; right < list.size(); ++right) {
            for (int left = 0; left < right; ++left) {
                if (toBeRemoved.contains(left)) {
                    continue;
                }
                Keep keep = chooser.choose(list.get(left), list.get(right));
                switch (keep) {
                    case LEFT:
                        toBeRemoved.add(right);
                        continue leftloop;
                    case RIGHT:
                        toBeRemoved.add(left);
                        break;
                    case NONE:
                        toBeRemoved.add(left);
                        toBeRemoved.add(right);
                        continue leftloop;
                }
            }
        }

        Collections.sort(toBeRemoved, new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return o2 - o1;
            }
        });

        for (int i : toBeRemoved) {
            if (i >= 0 && i < list.size()) {
                list.remove(i);
            }
        }
    }

    public static <T> void List(List<T> list, Keeper<T> keeper) {
        Iterator<T> iterator = list.iterator();
        while (iterator.hasNext()) {
            if (!keeper.keep(iterator.next())) {
                iterator.remove();
            }
        }
    }

    public interface Keeper<E> {
        boolean keep(E obj);
    }

    public interface Chooser<E> {
        Keep choose(E left, E right);
    }

    public enum Keep {
        LEFT, RIGHT, BOTH, NONE;
    }
}

这将被这样使用。

List<String> names = new ArrayList<>();
names.add("Anders");
names.add("Stefan");
names.add("Anders");
Filter.List(names, new Filter.Chooser<String>() {
    @Override
    public Filter.Keep choose(String left, String right) {
        return left.equals(right) ? Filter.Keep.LEFT : Filter.Keep.BOTH;
    }
});

我将把RxJava加入其中,它在Android上也可用。RxJava可能并不总是最好的选择,但如果您希望在集合上添加更多转换或在过滤时处理错误,RxJava将为您提供更大的灵活性。

Observable.from(Arrays.asList(1, 2, 3, 4, 5))
    .filter(new Func1<Integer, Boolean>() {
        public Boolean call(Integer i) {
            return i % 2 != 0;
        }
    })
    .subscribe(new Action1<Integer>() {
        public void call(Integer i) {
            System.out.println(i);
        }
    });

输出:

1
3
5

更多关于RxJava过滤器的细节可以在这里找到。

设置:

public interface Predicate<T> {
  public boolean filter(T t);
}

void filterCollection(Collection<T> col, Predicate<T> predicate) {
  for (Iterator i = col.iterator(); i.hasNext();) {
    T obj = i.next();
    if (predicate.filter(obj)) {
      i.remove();
    }
  }
}

的用法:

List<MyObject> myList = ...;
filterCollection(myList, new Predicate<MyObject>() {
  public boolean filter(MyObject obj) {
    return obj.shouldFilter();
  }
});

一些简单明了的Java代码怎么样

 List<Customer> list ...;
 List<Customer> newList = new ArrayList<>();
 for (Customer c : list){
    if (c.getName().equals("dd")) newList.add(c);
 }

简单、易读、简单(在Android上也适用!) 但如果你使用的是Java 8,你可以用一句简单的话来实现:

List<Customer> newList = list.stream().filter(c -> c.getName().equals("dd")).collect(toList());

注意,toList()是静态导入的

JFilter http://code.google.com/p/jfilter/最适合您的需求。

JFilter是一个简单、高性能的开源库,用于查询Java bean集合。

关键特性

Support of collection (java.util.Collection, java.util.Map and Array) properties. Support of collection inside collection of any depth. Support of inner queries. Support of parameterized queries. Can filter 1 million records in few 100 ms. Filter ( query) is given in simple json format, it is like Mangodb queries. Following are some examples. { "id":{"$le":"10"} where object id property is less than equals to 10. { "id": {"$in":["0", "100"]}} where object id property is 0 or 100. {"lineItems":{"lineAmount":"1"}} where lineItems collection property of parameterized type has lineAmount equals to 1. { "$and":[{"id": "0"}, {"billingAddress":{"city":"DEL"}}]} where id property is 0 and billingAddress.city property is DEL. {"lineItems":{"taxes":{ "key":{"code":"GST"}, "value":{"$gt": "1.01"}}}} where lineItems collection property of parameterized type which has taxes map type property of parameteriszed type has code equals to GST value greater than 1.01. {'$or':[{'code':'10'},{'skus': {'$and':[{'price':{'$in':['20', '40']}}, {'code':'RedApple'}]}}]} Select all products where product code is 10 or sku price in 20 and 40 and sku code is "RedApple".