Fab*_*ndl 86 java list filter guava
有没有理由呢
Lists.transform()
Run Code Online (Sandbox Code Playgroud)
但不是
Lists.filter()
Run Code Online (Sandbox Code Playgroud)
?
如何正确过滤列表?我可以用
new ArrayList(Collection2.filter())
Run Code Online (Sandbox Code Playgroud)
当然,但是如果我理解正确,这种方式并不保证我的订单保持不变.
Jon*_*eet 37
您可以使用Iterables.filter,这肯定会维持订购.
请注意,通过构建新列表,您将复制元素(当然只是引用) - 因此它不会是原始列表的实时视图.创建一个视图会非常棘手 - 考虑这种情况:
Predicate<StringBuilder> predicate =
/* predicate returning whether the builder is empty */
List<StringBuilder> builders = Lists.newArrayList();
List<StringBuilder> view = Lists.filter(builders, predicate);
for (int i = 0; i < 10000; i++) {
builders.add(new StringBuilder());
}
builders.get(8000).append("bar");
StringBuilder firstNonEmpty = view.get(0);
Run Code Online (Sandbox Code Playgroud)
这将不得不迭代整个原始列表,将过滤器应用于所有内容.我想它可能要求谓词匹配在视图的生命周期内没有变化,但这并不完全令人满意.
(请注意,这只是猜测.也许其中一个Guava维护者会填充真正的原因:)
ska*_*man 28
我
new List(Collection2.filter())当然可以使用,但这种方式不能保证我的订单保持不变.
事实并非如此. Collections2.filter()是一个延迟评估的函数 - 在您开始访问过滤后的版本之前,它实际上并不过滤您的集合.例如,如果迭代过滤后的版本,则过滤后的元素将以与原始集合相同的顺序从迭代器中弹出(减去过滤掉的那些,显然).
也许你认为它在前面进行过滤,然后将结果转储到某种形式的任意,无序的集合中 - 它没有.
因此,如果您使用输出Collections2.filter()作为新列表的输入,那么您的原始订单将被保留.
使用静态导入(和Lists.newArrayList函数),它变得相当简洁:
List filteredList = newArrayList(filter(originalList, predicate));
Run Code Online (Sandbox Code Playgroud)
请注意,虽然Collections2.filter不会急于在底层集合迭代,Lists.newArrayList 将 -它会提取过滤集合的所有元素,并将它们复制到一个新的ArrayList.
Pre*_*raj 12
正如Jon所说,您可以使用Iterables.filter(..)或者Collections2.filter(..)如果您不需要实时视图,则可以使用ImmutableList.copyOf(Iterables.filter(..))或者Lists.newArrayList( Iterables.filter(..))保持订购.
如果您对部分原因感兴趣,可以访问https://github.com/google/guava/issues/505了解更多详情.
总结其他人所说的内容,您可以轻松创建一个通用的包装器来过滤列表:
public static <T> List<T> filter(Iterable<T> userLists, Predicate<T> predicate) {
return Lists.newArrayList(Iterables.filter(userLists, predicate));
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
42573 次 |
| 最近记录: |