Java - 如果可能的话,是传递引用还是使用硬编码对象更好
Java - Is it better to pass reference or work with hardcoded objects if possible
是否值得编写更好的代码 (ClassB) 而不是使用两种单独的检查方法?所以主要问题是:当我假设 Class A 比 Class B 快一点时,我是否正确,或者它的差异并不重要并且传递变量(在这种情况下为列表)并不重要真的会影响生产力,即使这些列表每个都有 1000 个对象?对不起,如果这个问题很愚蠢。
public class ClassA implements Runnable {
ArrayList<Obj> list1;
ArrayList<Obj> list2;
boolean checkList1() {
for (Obj str : list1) {
if (str.check()) {
return true;
}
}
return false;
}
boolean checkList2() {
for (Obj str : list2) {
if (str.check()) {
return true;
}
}
return false;
}
@Override
public void run() {
checkList1();
checkList2();
}
}
或
public class ClassB implements Runnable {
ArrayList<Obj> list1;
ArrayList<Obj> list2;
boolean checkAnyList(ArrayList<Obj> list) {
for (Obj str : list) {
if (str.check()) {
return true;
}
}
return false;
}
@Override
public void run() {
checkAnyList(list1);
checkAnyList(list2);
}
}
你们在做同样的事情,所以没有区别。
一样做thing.So没有区别
要点是代码重复 - 您正在做两次 完全相同 的事情,请不要这样做。每当您必须更改某些内容时 - 至少有两个地方可能需要更改 - 很容易忘记。
更有趣的是,最终第二种方法可能会更快,因为只有一种方法JVM JIT
必须优化;假设 inline it
。
您可以自己测试一下,但最终差异几乎不存在,所以我会选择更易于阅读和维护的版本(我会说是版本 2)。
从 Java 8 开始,也可能是这样的:
//Note that this doesn't match your code exacly but you should get what I mean.
//Since you didn't provide any hint on how you'd use the return values of your methods I'm working on assumptions here.
boolean result = list1.stream().anyMatch(o -> o.check() ) &&
list2.stream().anyMatch(o -> o.check() ) ;
一个可能更好的变体,因为重构不需要您更改多个谓词,可能是这样的:
//Changes to how you'd check your elements would just require you to change this predicate.
Predicate<? super Obj> predicate = o -> o.check();
boolean result = list1.stream().anyMatch( predicate ) &&
list2.stream().anyMatch( predicate ) ;
最后还是量一下吧。为此,您可以使用像 System.nanoTime()
这样的高精度计时器
不测量我更喜欢B类。以下问题让classB更有趣
- 避免几乎重复的代码
- 引入更多列表时更灵活
- JIT 编译器根据调用次数改进代码。因此classB中的方法更早达到改进的阈值。
- 静态可用列表不太可能比引用列表更快。 classA 不传递列表的小优点,只节省了很少的启动时间。
等我得到真实数据....
是否值得编写更好的代码 (ClassB) 而不是使用两种单独的检查方法?所以主要问题是:当我假设 Class A 比 Class B 快一点时,我是否正确,或者它的差异并不重要并且传递变量(在这种情况下为列表)并不重要真的会影响生产力,即使这些列表每个都有 1000 个对象?对不起,如果这个问题很愚蠢。
public class ClassA implements Runnable {
ArrayList<Obj> list1;
ArrayList<Obj> list2;
boolean checkList1() {
for (Obj str : list1) {
if (str.check()) {
return true;
}
}
return false;
}
boolean checkList2() {
for (Obj str : list2) {
if (str.check()) {
return true;
}
}
return false;
}
@Override
public void run() {
checkList1();
checkList2();
}
}
或
public class ClassB implements Runnable {
ArrayList<Obj> list1;
ArrayList<Obj> list2;
boolean checkAnyList(ArrayList<Obj> list) {
for (Obj str : list) {
if (str.check()) {
return true;
}
}
return false;
}
@Override
public void run() {
checkAnyList(list1);
checkAnyList(list2);
}
}
你们在做同样的事情,所以没有区别。
一样做thing.So没有区别
要点是代码重复 - 您正在做两次 完全相同 的事情,请不要这样做。每当您必须更改某些内容时 - 至少有两个地方可能需要更改 - 很容易忘记。
更有趣的是,最终第二种方法可能会更快,因为只有一种方法JVM JIT
必须优化;假设 inline it
。
您可以自己测试一下,但最终差异几乎不存在,所以我会选择更易于阅读和维护的版本(我会说是版本 2)。
从 Java 8 开始,也可能是这样的:
//Note that this doesn't match your code exacly but you should get what I mean.
//Since you didn't provide any hint on how you'd use the return values of your methods I'm working on assumptions here.
boolean result = list1.stream().anyMatch(o -> o.check() ) &&
list2.stream().anyMatch(o -> o.check() ) ;
一个可能更好的变体,因为重构不需要您更改多个谓词,可能是这样的:
//Changes to how you'd check your elements would just require you to change this predicate.
Predicate<? super Obj> predicate = o -> o.check();
boolean result = list1.stream().anyMatch( predicate ) &&
list2.stream().anyMatch( predicate ) ;
最后还是量一下吧。为此,您可以使用像 System.nanoTime()
不测量我更喜欢B类。以下问题让classB更有趣
- 避免几乎重复的代码
- 引入更多列表时更灵活
- JIT 编译器根据调用次数改进代码。因此classB中的方法更早达到改进的阈值。
- 静态可用列表不太可能比引用列表更快。 classA 不传递列表的小优点,只节省了很少的启动时间。
等我得到真实数据....