番石榴迭代器,以及迭代列表对象中的列表

2022-09-04 00:47:32

我有以下示例代码,它由3个嵌套的for循环组成。

for(Continent continent : continentList) 
{
    for(Country country : continent.getCountries())
    {
        for(City city : country.getCities())
        {
            //Do stuff with city objects
        }
    }
}

有没有办法使用番石榴和迭代器来模仿这个嵌套的for循环?我一直试图找到一个合适的例子,但没有多少运气,我想知道是否有人可以帮助我?我的一位同事提到使用过滤器。

编辑:修复了示例代码中的小错误


答案 1

正如 Peter Lawrey 所评论的那样,这几乎肯定会像嵌套循环一样简单。此外,番石榴文档给出了以下警告:

命令式代码应该是你的默认代码,从Java 7开始,你的首选。除非您绝对确定以下情况之一,否则不应使用功能性习语:

  • 使用功能习语将为整个项目节省代码行的净成本。将函数的定义移动到另一个文件或常量是没有帮助的。
  • 为了提高效率,您需要一个经过转换的集合的延迟计算视图,并且不能满足于显式计算的集合。此外,您已经阅读并重新阅读了 Effective Java,第 55 项,除了遵循这些说明之外,您实际上还进行了基准测试,以证明此版本更快,并且可以引用数字来证明这一点。

请注意,在使用番石榴的功能实用程序时,传统的命令式做事方式不是更具可读性。试着把它写出来。那有那么糟糕吗?这是否比你即将尝试的荒谬笨拙的功能方法更具可读性?

但是,如果你坚持要忽略建议,你可以使用类似这样的东西(注意我实际上并没有尝试编译或运行这个):

FluentIterable.from(continentList)
    .transform(new Function<Continent, Void>() {
        public Void apply(Continent continent) {
            return FluentIterable.from(continent.getCountries())
                .transform(new Function<Country, Void>() {
                    public Void apply(Country country) {
                        return FluentIterable.from(country.getCities())
                            .transform(new Function<City, Void>() {
                                public Void apply(City city) {
                                    // do stuff with city object
                                    return null;
                                }
                            });
                    }
                });
        }
    });

现在问问自己:你想维护哪个?哪个最有效?

番石榴的功能习语有有效的用例。替换 Java for 循环,甚至是嵌套的循环,都不是其中之一。


答案 2

您可以为以下对象定义静态函数:
• getCountries() in Continents, Continents or Functions
• getCities() in Country, Country or Functions

现在你可以做这样的事情...

FluentIterable.from(continentList)
    .transformAndConcat(Continent.getCountriesFunction())
    .transformAndConcat(Country.getCitiesFunction())
    . //filter //tranform //find //toList() //etc.

如果:
•您经常像这样(更多)使用番石榴。
•并就定义函数和谓词的位置有一定的规则/想法。
•并且有各种(复杂)的东西要过滤或搜索。
然后,它可以是一个巨大的福音,可以使许多情况变得容易得多。我知道我很高兴我做到了。

如果你很少使用它,那么我必须同意@Louis Wasserman的观点。那么就不值得麻烦了。此外,将函数和谓词定义为匿名内部类,就像其他示例一样...真是丑。