有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

Java如何在for循环中使用getter?

例如,如果我有下面的For循环声明

for(Foo f : fooService.getFooList()){}

首先调用getter并将其分配给临时List<Foo> fooList = fooService.getFooList();更有效还是可以使用getter内联


共 (4) 个答案

  1. # 1 楼答案

    首先分配给列表引用并不更有效,但是拥有引用可能会很有用,这取决于您试图做什么

  2. # 2 楼答案

    完全一样。getter只调用一次,而不是在完成每个循环之前。如果需要,请将其指定给变量,否则不需要

    仅供参考:在幕后List将不会被使用,而是它的Iterator

    因此,您的for循环可以这样表述:

    for (Iterator<Foo> i = fooService.getFooList(); i.hasNext();) {
        Foo foo= i.next();
    }
    

    有关更多信息,请参见language specifications about the ^{} loops

  3. # 3 楼答案

    在这种特定情况下,使用foreach循环,我希望您的代码将编译为如下内容:

    Iterator<Foo> it = fooService.getFooList().iterator();
    while (it.hasNext()) {
        Foo foo = it.next();
        // ...
    }
    

    所以在这种情况下,这没有什么区别

    然而,如果您要使用不同类型的循环,那么它可能会有所不同。例如:

    for(int i = 0; i < fooService.getFooList().size(); i++){
        Foo foo = fooService.getFooList().get(i);
        // ...
    }
    

    如果您的列表暴露于外部修改,那么编译器不太可能证明列表大小不会改变,因此它将在每次迭代中调用getFooList().size()i进行比较,因此会稍微增加一些开销

    但是请注意,如果列表大小改变,那么i < fooService.getFooList().size()反映了这一点。如果你意识到这一点,这可能是有用的,但如果你没有意识到这一点,则是危险的

    如果您知道列表大小不会改变,那么您可以这样做以消除开销(或者在不需要索引的情况下对每个循环使用Iterator或增强):

    List<Foo> fooList = fooService.getFooList();
    final int fooListSize = fooList.size();
    for(int i = 0; i < fooListSize ; i++){
        Foo foo = fooList.get(i);
        // ...
    }
    

    尽管如此,与微优化相比,您可能更喜欢可读性

    但是,如果您的应用程序是运行时敏感的,并且您的列表很大,并且这些小检查正在累积,那么您可能需要执行类似于上面的操作

  4. # 4 楼答案

    如果您关心的是fooService.getFooList()被调用n次以获取每个值f,那么忽略这个想法。这将调用getFooList()一次并迭代其结果

    例如,在以下snippet中:

    class Ideone
    {
        private static List<String> list = Arrays.asList("A", "B", "C");
    
        public static void main (String[] args) throws java.lang.Exception
        {
            for(String f : getFooList()){
               System.out.println(f);
            }
        }
    
        private static List<String> getFooList() {
            System.out.println("getFooList called");
            return list;
        }
    }
    

    getFooList called只打印一次,这表示for循环只调用了一次方法getFooList()。在这之后,它被打印ABC,对从方法调用中获得的元素进行迭代

    因此,就效率而言,直接调用getter或将其分配给变量并使用其执行迭代是相同的