有人可以解释一下Optional我们如何避免NullPointerException吗?
Optional<String> op = someFunc()
if(op.isPresent()) {
op.get();
}
String possibleNull = op.get();
Run Code Online (Sandbox Code Playgroud)
这个代码不是很容易出现NullPointerException吗?如果是这样,那么为什么这个代码更受欢迎
String op = someFunc()
if(op != null) {
op.get();
}
String possibleNull = op;
Run Code Online (Sandbox Code Playgroud)
Optional除了帮助我们了解函数是否实际具有返回值之外,还有什么可能带来的好处
让我们考虑一下 HashMap
HashMap<String, String> map = new HashMap<String, String>();
Run Code Online (Sandbox Code Playgroud)
我在地图中有值
map.put("model", "test");
Run Code Online (Sandbox Code Playgroud)
目前,如果我想从我正在做的地图中获取价值
if(map!=null){
if(map.get("model")!=null && !map.get("model").isEmpty()){
//some logic
}
}
Run Code Online (Sandbox Code Playgroud)
通过使用Optional或Lambdas来实现上述条件,Java 8中是否有更好的方法?
我有一段代码,其中一个接口有一个Optional返回方法,一些类实现它返回一些东西,其他没有.
为了拥抱这个辉煌的"空杀手",这是我尝试过的:
public interface Gun {
public Optional<Bullet> shoot();
}
public class Pistol implements Gun{
@Override
public Optional<Bullet> shoot(){
return Optional.of(this.magazine.remove(0));
}//never mind the check of magazine content
}
public class Bow implements Gun{
@Override
public Optional<Bullet> shoot(){
quill--;
return Optional.empty();
}
}
public class BallisticGelPuddy{
private Gun[] guns = new Gun[]{new Pistol(),new Bow()};
private List<Bullet> bullets = new ArrayList<>();
public void collectBullets(){
//here is the problem
for(Gun gun : guns)
gun.shoot.ifPresent(bullets.add( <the return I got with the method>)
}} …Run Code Online (Sandbox Code Playgroud) Scala具有部分函数,这些函数仅适用于输入类型的某些值,但不是全部:
val isEven: PartialFunction[Int, String] = {
case x if x % 2 == 0 => x+" is even"
}
assert(isEven(10) equalsIgnoreCase "10 is even")
assert(isEven.isDefinedAt(11) == false)
Run Code Online (Sandbox Code Playgroud)
而且,更有用的是,scala允许将"partialness"应用于a的子类型trait:
sealed trait BaseTrait
case class Foo(i : Int) extends BaseTrait
case class Bar(s : String) extends BaseTrait
val fooPartialFunc : PartialFunction[BaseTrait, Int] = {
case f : Foo => 42 + f.i
}
assert(fooPartialFunc(Foo(8)) == 50)
assert(fooPartialFunc.isDefinedAt(Bar("hello")) == false)
Run Code Online (Sandbox Code Playgroud)
java 8中的等价物是什么?
大多数谷歌搜索结果混淆了"部分功能"与currying,例如"部分应用功能".
考虑这个表达式的用法:
String hi = Optional.ofNullable(sayHi()).orElse("-");
Run Code Online (Sandbox Code Playgroud)
这有效地对应于这个三元表达式:
String hi = sayHi() != null ? sayHi() : "-";
Run Code Online (Sandbox Code Playgroud)
使用Optional.ofNullable方法调用是一种好习惯吗?或者只是额外的详细编码?
我认识到Optional.ofNullable实际上创建了一个变量并避免了sayHi()两次调用该方法.为了避免这个问题,你实际上可以创建一个额外的变量,但这会增加三元选项的详细程度:
String hi = sayHi();
hi = hi != null ? hi : "-";
Run Code Online (Sandbox Code Playgroud)
另一方面,Optional.ofNullable在hi不是null额外Optional对象的情况下创建.所以肯定会有更多的开销.
因此,使用这种类型的构造来替换三元构造函数似乎有一些利弊.
顺便说一下:这是Java 8的实现Optional.ofNullable:
public static <T> Optional<T> ofNullable(T value) {
return value == null ? empty() : of(value);
}
Run Code Online (Sandbox Code Playgroud) 您好,我有两个代码示例
if / else if / else语句
private Object getObj(message) {
if (message.getA() != null)
return message.getA();
else if (message.getB() != null)
return message.getB();
else if (message.getC() != null)
return message.getC();
else return null;
}
Run Code Online (Sandbox Code Playgroud)
可选陈述
private Optional<Object> wrap(Object o){
return Optional.ofNullable(o);
}
private Object getObj(message) {
return wrap(message.getA())
.orElseGet(() -> wrap(message.getB())
.orElseGet(() -> wrap(message.getC())
.orElse(null)));
}
Run Code Online (Sandbox Code Playgroud)
所以我的问题是,这两者在性能方面如何比较(我在实际代码中大约有15-20条if-else语句)?
值得重构代码的可读性和性能,还是滥用可选选项?
另外,如果if / else-if语句增长到100+,性能损失会是多少?
提前致谢
假设我有这样一个类:
public static class Test {
private Optional<String> something;
public Optional<String> getSomething() {
return something;
}
public void setSomething(Optional<String> something) {
this.something = something;
}
}
Run Code Online (Sandbox Code Playgroud)
如果我反序列化这个JSON,我得到一个空的可选:
{"something":null}
Run Code Online (Sandbox Code Playgroud)
但是如果缺少属性(在这种情况下只是空JSON),我得到null而不是Optional.我当然可以自己初始化字段,但我认为最好有一个null和缺少属性的机制.那么有没有办法让jackson反序列化缺少的属性为空可选?
有一个可选的可选列表,例如:
Optional<List<Optional<String>>> optionalList = Optional.of(
Arrays.asList(
Optional.empty(),
Optional.of("ONE"),
Optional.of("TWO")));
Run Code Online (Sandbox Code Playgroud)
如何遍历optionalList以打印出字符串的ONEand TWO?
有一个可选的可选流怎么样?
Optional<Stream<Optional<String>>> optionalStream = Optional.of(
Stream.of(
Optional.empty(),
Optional.of("ONE"),
Optional.of("TWO")));
Run Code Online (Sandbox Code Playgroud)
更新:感谢您的回答,optionalStream 的解决方案(非嵌套):
optionalStream
.orElseGet(Stream::empty)
.filter(Optional::isPresent)
.map(Optional::get)
.forEach(System.out::println);
Run Code Online (Sandbox Code Playgroud) 如果不是,我有一个BigDecimal我想要投射的金额,但我做了一个例外:Longnulljava.lang.NullPointerException
BigDecimal bgAmount = getAmount();
long totalSupplyFilterMin =
Optional.ofNullable(bgAmount.longValue()).orElse(Long.MIN_VALUE);
Run Code Online (Sandbox Code Playgroud) 我正在解析输入JSON.对于一个领域,有三种可能性:
实现了不同的行为:对于JSON中缺少的值,将默认值插入到数据库中; 对于JSON中的空值,将空值插入到数据库中.
我Optional想要模仿这个:
public class Data {
private Optional<String> field;
}
Run Code Online (Sandbox Code Playgroud)
以下哪两个选项最有意义?
field为null,则JSON中不存在该字段.如果field是Optional.empty,则该字段null位于JSON中.field为null,则该字段null位于JSON中.如果field是Optional.empty,则JSON中不存在该字段.FWIW,我使用Jackson和模块jackson-datatype-jdk8来解析输入JSON.
java ×10
java-8 ×10
optional ×7
jackson ×2
json ×2
bigdecimal ×1
dictionary ×1
if-statement ×1
java-stream ×1
lambda ×1
null-check ×1
nullable ×1
performance ×1
scala ×1