我开始学习如何在Java8中使用Optional
进行开发。可能是在这里有记录,但是我一直在使用google,但没有准确的结果。
对于orElseGet
方法,我有不同的可能实现,而且我不确定java在某些情况下是否可以实现更好的内存处理,或者它是否大致相同。
假设我在一个类中定义了Optional
的方法:
class myClass {
final static private Supplier<Object> MY_SUPPLIER = () -> new Object();
private void myMethod1 () {
Optional<Object> x; // somehow Initialized
Object y = x.orElseGet(() -> new Object());
}
private void myMethod2 () {
Optional<Object> x; // somehow Initialized
Object y = x.orElseGet(MY_SUPPLIER);
}
}
从我卑微的角度来看,此秒应该在Java中具有更好的内存管理,因为它只被Supplier
声明一次,并且始终使用相同的方式。
1)是真的吗?
现在,让我们更进一步,想象我们需要根据参数提供不同的对象。
class myClass2 {
final static private Function<String, Supplier<AnyCustomClass>> MY_SUPPLIER_PROVIDER = (p) -> () -> new AnyCustomClass(p);
private void myMethod1 (String arg) {
Optional<AnyCustomClass> x; // somehow Initialized
AnyCustomClass y = x.orElseGet(() -> new AnyCustomClass(arg));
}
private void myMethod2 (String arg) {
Optional<AnyCustomClass> x; // somehow Initialized
AnyCustomClass y = x.orElseGet(MY_SUPPLIER_PROVIDER.apply(arg));
}
}
在这种情况下,根据参数,每次返回不同的供应商。
2)Java在这里也有更好的内存管理吗?
3)他们是否因为arg值相同而以某种方式被“缓存”了?
编辑
通过观看Does a lambda expression create an object on the heap every time it's executed? ,我了解到我的一流行为得到了回答。由于没有局部变量,它将创建一个单例(至少是oracle jvm)
但是,我不认为该答案可以提供准确的信息来回答我的2)和3)
答案 0 :(得分:1)
这两种方法之间的区别是您正在重用供应商,这将重用对象,从而节省了一些内存。您需要注意的是可能存在线程问题。由于您使用的是相同的内存,因此需要确保不同的线程不要尝试使用同一对象。
所以回答您的问题:
1。)是,但是您可能还有其他问题。
2。)与第一个问题相同吗?您正在重用Function的实例。这不是您应该在这种情况下使用Function的方式。
3。)它被“缓存”,因为该函数的实例被重用。
通常来说,我会远离您的第二选择,除非被称为1000 /秒,否则您要交易的是增加的复杂性,而这不会转化为明显的性能。
如果您对性能表现感兴趣,请编写一个单元测试,在不同的线程上多次调用此测试,并使用探查器监视运行情况。