使用变量而不是长语句?

时间:2016-10-07 04:01:59

标签: java

我在处理对象时遇到了困惑。我搜索谷歌但无法找到要搜索的实际单词。问题是:

我正在使用包含其他对象的对象。例如:

 public void mapObjects(A a, B b) {
    a.setWeight(BigDecimal.valueOf(b.getWeight));
    //Now my doubt lies here
    if (a.getCharges.getDiscounts.getDiscountList != null) {
      for(int i = 0; i < a.getCharges.getDiscounts.getDiscountList.size(); i++){
          b.getList().get(0).setDiscountValue(a.getCharges.getDiscounts.getDiscountList.get(i).getValue());
          b.getList().get(0).setDiscountName(a.getCharges.getDiscounts.getDiscountList.get(i).getValue);
      }
    }

}

以上代码只是一个例子。我工作的项目使用类似的编码风格。使用a.getCharges.getDiscounts.getDiscountList()类代码总是让我烦恼。因为我一次又一次地喊同样的声明。

当我问一位大四学生为什么不把这句话保存到一个简单的List&lt;&gt;变量。他告诉我它将使用额外的引用,这将增加开销。可以使用变量比一次又一次地调用getter要多得多吗?

4 个答案:

答案 0 :(得分:2)

由于Java交换引用的不是实际对象,如果你接受局部变量,它只会在堆栈框架中添加引用变量条目。

  • 这个记忆会非常少,几乎可以忽略不计
  • 一旦方法完成,将释放此内存,因为这将是方法的本地

尽管如此,如果使用局部变量,可以获得显着的性能提升。您在循环内多次提取相同的信息。

    多次调用
  1. a.getCharges.getDiscounts.getDiscountList.size()。它应该是一个局部变量。
  2. b.getList().get(0)被多次调用。它应该是一个局部变量。
  3. 多次调用
  4. a.getCharges.getDiscounts.getDiscountList。它应该是一个局部变量。
  5. 将这些更改为局部变量可以获得良好的性能提升,因为可以节省不必要的方法调用。

答案 1 :(得分:1)

将你的大四学生指向this。如果它适用于Android上的有限资源,我想在本地变量中存储for循环中使用的所有内容的技术实际上对任何地方的性能都有益。

在下面的摘录中,请注意我们甚至没有谈到通过调用(虚拟)list.size()方法引入的开销,只将array.length存储为局部变量会产生明显的差异在表现。

public void zero() {
    int sum = 0;
    for (int i = 0; i < mArray.length; ++i) {
        sum += mArray[i].mSplat;
    }
}

public void one() {
    int sum = 0;
    Foo[] localArray = mArray;
    int len = localArray.length;

    for (int i = 0; i < len; ++i) {
        sum += localArray[i].mSplat;
    }
}

public void two() {
    int sum = 0;
    for (Foo a : mArray) {
        sum += a.mSplat;
    }
}
  

零()是最慢的,因为JIT无法优化通过循环每次迭代获得一次数组长度的成本。

     

一个()更快。它将所有内容都拉到局部变量中,避免了查找。只有阵列长度才能提供性能优势。

     对于没有JIT的设备,

two()最快,而对于具有JIT的设备,

两()无法区分。它使用Java编程语言1.5版中引入的增强型for循环语法。

答案 2 :(得分:0)

只需使discountList字段永不为null - 即初始化为空列表 - 并迭代它。类似的东西:

for (Discount discount : a.getCharges().getDiscounts().getDiscountList()) {
    b.getList().get(0).setDiscountValue(discount.getValue());
    b.getList().get(0).setDiscountName(discount.getName());
}

您的“老年人”可能需要做一些研究。这样做的“性能影响”是每个对象几个字节,每次访问几微秒。如果他真的对内存感兴趣,可以使用LinkedList初始化它,它几乎没有内存占用。

答案 3 :(得分:0)

在Java中,指向对象实例V的变量O只是一个数值,指向存储对象数据的内存位置。

当我们将V分配给另一个变量V1时,所有发生的事情都是V1现在指向存储O数据的相同内存位置。这意味着当您执行简单赋值时不会分配新内存,而不像C ++代码那样可以重载=运算符来执行深拷贝,在这种情况下实际分配了新内存。以下面的例子说明

考虑下面的课程

class Foo {

   private List<String> barList = new ArrayList<>();

   //class methods...

  //getter for the list
  List<String> getBarList() {
      return this.barList;
  }
}

public static void main(String[] args) {

   Foo f = new Foo()
   //the below lien will print 0 since there is no bar string added
   System.out.println("Bar list size: " + f.getBarList().size());

  // add a bar string. Observe here that I am simply getting the list 
  // and adding - similar to how your code is currently structured
  f.getBarList().add("SomeString");
  //now get a reference to the list and store it in a variable. 
  // Below anotherList only points to the same memory location 
  // where the original bar list is present. No new memory is allocated.
  List<String> anotherList = f.getBarList();
  //print the content of bar list and another list. Both will be same
  for(String s : f.getBarList()) {
     System.out.println(s);
  }
  for(String s: anotherList) {
    System.out.println(s);
  }

  //add a new bar string using the reference variable
  anotherList.add("Another string");
  //print the content of bar list and another list. Both will be same. If anotherList had separate memory allocated to it then the new string added would be only seen when we print the content of anotherList and not when we print the content of f.getBarList(). This proves that references are only some numeric addresses that point to locations of the object on heap.
  for(String s : f.getBarList()) {
     System.out.println(s);
  }
  for(String s: anotherList) {
    System.out.println(s);
  }

}

希望这有帮助。