2011-07-27 32 views
4

我在学习番石榴。然而,我并不是很成功,因为它的教程非常少。如何在番石榴中进行迭代

任何机构可以告诉我如何在番石榴写这段代码。

import java.util.*; 

public class list { 
    public static void main(String[] args) { 
    List l = new ArrayList(); 
    for (int i = 1; i < 6; i++) { 
     l.add(i); 
    } 
    Iterator it = l.iterator(); 
    while (it.hasNext()) { 
     System.out.println(it.next()); 
    } 
    } 
} 

回答

3

番石榴(据我所知)不提供任何功能来简化您发布的代码。

,我可以建议的唯一的改进是使用generics,并使用enhanced for loop遍历列表,而不是如何获取并使用迭代明确:

import java.util.*; 

public class list { 
    public static void main(String[] args) { 
    List<Integer> l = new ArrayList<Integer>(); 
    for (int i = 1; i < 6; i++) { 
    l.add(i); 
    } 

    for(Integer i : l) { 
    System.out.println(i); 
    } 

} 
3

由于@Jared罗素指出的那样,这并不完全是展示Guava如何帮助您在代码中实现的改进的最佳示例。

这就是说,如果你只是在寻找的番石榴如何才能找到自己的方式进入这个代码演示,这里是一个镜头:

我在这里使用
import com.google.common.base.Joiner; 
import com.google.common.collect.ImmutableList; 
import com.google.common.collect.ImmutableList.Builder; 

public class Question6842887 { 
public static void main(String[] args) { 
    Builder<Integer> builder = ImmutableList.builder(); 
    for (int i = 1; i < 6; i++) { 
     builder.add(i); 
    } 

    ImmutableList<Integer> list = builder.build(); 

    System.out.println(Joiner.on(System.getProperty("line.separator")).join(list)); 
} 

两个番石榴事情是immutable listsjoiner

这可能不是您通常需要ImmutableList的情况类型,但不管怎样习惯使用它都是很好的做法。不可变集合(以及任何不可变对象)的巨大优势在于它们是线程安全的。你永远不需要做出防御性的副本,或者在关闭内容后改变其内容。你可以简单地自由传递它,或者缓存它,并且对它的不变性感到高兴和安全。欲了解更多有关不变性问题的信息,我会参考Effective Java,第15项。

我在这里演示的另一个番石榴班是乔伊纳。 Joiner只是一个很好而简单的方法,可以将一组字符串与分隔符组合在一起。这是相当可定制的,你可以指定它将如何处理空值以及你想要使用哪个分隔符。在这种情况下,我已指定System.getProperty("line.separator")作为我的分隔符;你可以选择使用", "或类似的。我还选择不处理空值,因为我知道我们的ImmutableList中没有空值。但是,如果您的列表可能具有空值,您可以选择一个选项,如skipNullsuseForNull

番石榴的下一个版本预计将包括Range的支持。这可以用来简化你的列表建设到像ContiguousSet<Integer> list = Ranges.closedOpen(1, 6).asSet(DiscreteDomains.integers());虽然我不推荐它,你的整个程序可能是一行。

+0

和Jared Russell ...使用番石榴可以使迭代比通常的Java集合更快...像(Iterator itr = appCodeCombos.iterator(); itr.hasNext();) – Enosh

+0

我不希望有性能利用显式迭代器的“增强for循环”对循环的好处。我期望(尽管我没有对它进行基准测试),Joiner解决方案会更快一些,因为你只有一个调用慢速的System.out.println。 – Ray

+0

使用谷歌收藏将代码执行更快,没有问题,即使它在微秒内运行得更快 – Enosh

5

番石榴即将到来的10版本将会使这种初始化的更痛苦:

List<Integer> l = Lists.newArrayList(
     Ranges.closed(1, 5).asSet(DiscreteDomains.integers()) 
); 
for (Integer item : l) { 
    System.out.println(item); 
} 

(没有发行10,但你可以下载源代码,并建立它自己)

+0

这看起来错了 - 我希望现实世界会说服番石榴提交者忘记域名。这种方法似乎比用函数等效替换运算符更加愚蠢...... –

+0

@Gabriel我不同意,这是我绝对期待的功能之一。是的,我更喜欢没有DiscreteDomains的Ranges,但我必须同意它们会更模糊,更不用说普遍有用。 –

+0

不要误解我的意思,我也期待Ranges,但我认为20%的用例使用80%的时间不需要域名。 –

1

在这种特殊情况下,不需要使用列表 - 正如@Sean Patrick Floyd通过使用范围所示 - 您正在迭代的集合是一组数字 - 所以列表并不是真正使用的最佳类型。

使用番石榴增强了我对“编程到最普通类型”的决心 - 而且我发现自己越来越依赖于可编程的编程 - 在之前,出于某种原因,我认为Collection是这些类型中最抽象的类型用例。

番石榴的Iterables类对于处理Iterable类型非常有用,我认为它确实导致了很多更好的代码。

利用番石榴的我的当前版本(12.0) - 一个干净的方式来写,这将是:

Iterable<Integer> l = Ranges.closed(1, 5).asSet(DiscreteDomains.integers()); 
for (Integer item : l) { 
    System.out.println(item); 
} 

编辑

这是一个很好的博客文章here从一个创作者关于为什么不编程到Iterable(小猫死亡......等)的节日断言。在任何情况下,我仍然不完全相信它的恶意,但我可以承认,在某些情况下,对于使用你的代码的人来说非常苛刻 - 特别是在API设计的情况下。

+1

在最近的避免弃用错误的应用中,它应该是'ContiguousSet.create(Range.closedOpen(1,6),DiscreteDomains。整数())'(我几乎总是喜欢closedOpen范围) –

+0

顺便说一下,我认为post的想法是错误的。 (< - 那个时期)以方便的名义增加复杂性真是糟糕的主意(参见Rich Hickey关于简单性的一些谈话)。 –