我想根据谓词筛选java.util.Collection。
当前回答
我需要根据列表中已经存在的值来筛选列表。例如,删除后面小于当前值的所有值。{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;
}
});
其他回答
使用java 8,特别是lambda表达式,你可以像下面的例子那样简单:
myProducts.stream().filter(prod -> prod.price>10).collect(Collectors.toList())
其中,对于myProducts集合中的每个产品,如果prodc .price>10,则将该产品添加到新的过滤列表中。
从java 9开始收集。启用过滤:
public static <T, A, R>
Collector<T, ?, R> filtering(Predicate<? super T> predicate,
Collector<? super T, A, R> downstream)
因此过滤应该是:
collection.stream().collect(Collectors.filtering(predicate, collector))
例子:
List<Integer> oddNumbers = List.of(1, 19, 15, 10, -10).stream()
.collect(Collectors.filtering(i -> i % 2 == 1, Collectors.toList()));
使用来自Apache Commons的CollectionUtils.filter(Collection,Predicate)。
Java集合流的一个替代(更轻量级的)选择是Ocl.java库,它使用vanilla集合和lambdas: https://github.com/eclipse/agileuml/blob/master/Ocl.java
例如,对数组列表中的单词进行简单的筛选和求和 可能是:
ArrayList<Word> sel = Ocl.selectSequence(words,
w -> w.pos.equals("NN"));
int total = Ocl.sumint(Ocl.collectSequence(sel,
w -> w.text.length()));
Where Word有字符串pos;字符串文本;属性。效率似乎与流选项相似,例如,在两个版本中,10000个单词在大约50毫秒内处理。
Python、Swift等都有等效的OCL库。基本上,Java集合流重新发明了OCL操作——>select, ->collect等,这些操作自1998年以来就存在于OCL中。
在Java 8中,您可以直接使用此过滤器方法,然后执行此操作。
List<String> lines = Arrays.asList("java", "pramod", "example");
List<String> result = lines.stream()
.filter(line -> !"pramod".equals(line))
.collect(Collectors.toList());
result.forEach(System.out::println);
推荐文章
- 使用Jackson将JSON字符串转换为漂亮的打印JSON输出
- Android - SPAN_EXCLUSIVE_EXCLUSIVE跨度不能为零长度
- Javadoc @see或{@link}?
- 在准备语句中使用“like”通配符
- Android Eclipse -无法找到*.apk
- javac和Eclipse编译器之间的区别是什么?
- 工厂模式和策略模式之间的区别是什么?
- 在Java中使用正则表达式提取值
- 如何允许所有网络连接类型HTTP和HTTPS在Android(9)馅饼?
- Intellij IDEA Java类在保存时不能自动编译
- 何时使用Mockito.verify()?
- 在maven中安装mvn到底做什么
- 不可变与不可修改的集合
- 如何在JSON中使用杰克逊更改字段名
- GSON -日期格式