1

我有一个包含许多条目的大型集合:Set<File> allFiles.

使用以下算法迭代此 Set是否可行?有更好的方法吗?

Set<File> allFiles = // ...100,000+ entries
Set<File> filteredList = new LinkedHashSet<File>();

FileNameExtensionFilter filter = new FileNameExtensionFilter("Extensions accepted", "a", "b", "c");

for (File file : allFiles) {
    if (filter.accept(file)) {
        filteredList.add(file);
    }
}

如果有人问,allFilesSet 会在其他地方预先填充,不一定使用 File.listFiles() 方法收集。

4

3 回答 3

4

如果实际上你的意思是在 java 中可以写成 5 行,是的。当您想要过滤列表时,没有更简洁的选择(与具有功能结构的语言(如 Scala 及其过滤器方法)相反)。

我个人看不出你怎么能做得更好,如果你的用例真的要过滤掉扩展名不好的文件,我会在 Java 中做同样的事情。

如果您担心使用javax.swing不应该使用的接口和类,那么这两个类都只依赖于java.ioor java.util.Locale(用于根据英语语言环境将文件名设置为小写),因此它们与FilenameFilterfrom一样干净java.io。如果您的交易真的是根据不区分大小写的扩展名进行过滤,那么您绝对应该这样做,我的 Eclipse 看到的唯一选择是com.google.gwt.thirdparty.guava.common.io.PatternFilenameFilterimplementation java.io.FilenameFilter,但是您有一个新的依赖项,并且您编写了一个 Regex 模式,它的可读性和可维护性远低于您的扩展名。FileNameExtensionFilter所以如果这真的是你的用例,我会留下来 。

于 2012-08-30T07:44:39.830 回答
2

我不明白这怎么会不切实际。它不应该比迭代并添加到 Lists 而不是 Set 慢得多(尽管这仍然会稍微快一些并且使用更少的内存)。但是,如果您有充分的理由使用 Set(例如,您想要独特的元素和/或想要快速查询成员资格),我认为您会没事的。

尽管如果不查看其余代码就很难说。我建议你自己测试一下。

于 2012-08-30T07:44:29.427 回答
0

像其他人建议的那样,您有适当的方法来过滤集合。我唯一想做的就是使用CollectionUtils.html#filterapache commons 来使我的代码更具可读性和易于维护。

于 2012-08-30T07:50:34.783 回答