Guava:是否有可能不使用Multimaps.index()映射所有条目?

时间:2014-09-17 17:45:29

标签: java guava multimap

我有一些文件集合,其中一些不符合某些要求,另一些则没有。我想在一次迭代中对这些文件进行索引并丢弃无用的文件。 我希望在一次迭代中完成,因为数字相当大。

所以,我在考虑使用Multimaps.index():

// This is the file list to work on
Collection<File> fileList = FileUtils.listFiles(pathToCtrFiles,
                                                new String[]{"gz"},false);

// Now I want to index the files according to some condition in the file name (a pattern)
ImmutableListMultimap<ENBEquipment, File> mappedFiles = Multimaps.index(fileList, 
new Function<File,ENBEquipment>()
{
    @Override
    public ENBEquipment apply(File input)
    {
        Matcher m = p.matcher(input.getName());
        if (m.matches()){
            return enodebByMacroEnbIdMap.get(m.group(2));
        }

        // I am not interesting in these files. What can I do?
        return null;
    }
});

但是,无法按照API中的规定执行此操作:

  

抛出:   NullPointerException - 如果满足以下任何一种情况:   值为null   keyFunction为null   值中的元素为null   keyFunction为值

的任何元素返回null

所以我的问题是,你有一个优雅的方法来做这个,而不是两次迭代文件列表吗?

注意:我在考虑返回一个虚拟元素,但返回的列表是不可变的(没有机会删除它)。

2 个答案:

答案 0 :(得分:2)

在这种情况下只需手动编制索引(如果您将部分值遗漏掉,您甚至不会真正编制索引)。

ImmutableListMultimap.Builder<ENBEquipment, File> builder =
    ImmutableListMultimap.builder();
for (File file : fileList) {
  Matcher m = p.matcher(file.getName());
  if (m.matches()) {
    builder.put(enodebByMacroEnbIdMap.get(m.group(2)), file);
  }
}
ImmutableListMultimap<ENBEquipment, File> mappedFiles = builder.build();

它出现的线数更少,而且更具可读性。

答案 1 :(得分:0)

您可以在创建新列表时删除虚拟元素。但使用假人不是很干净。

我想,您可以在将fileList传递到Multimaps.index之前对其进行过滤。过滤谓词应该只测试你的匿名函数是否返回非null