我正在使用不可变地图
public Map<String,String> getMap(){
return ImmutableMap.<String,String>builder()
.put("FOO",getFooType())
.put("BAR", getBarType())
.build();
}
在某些情况下,getFooType()
或getBarType()
将返回null。这会导致从com.google.common.collect.ImmutableMap
抛出异常。我想知道是否有一种优雅的方法只使用非空和非空字符串填充地图。
我对任何Map实现都没问题,不仅限于番石榴库。
我可以取消以下
Map<String,String> map = new HashMap<>();
String fooType = getFooType();
String barType = getBarType();
if (fooType!=null && fooType.length()>0){
map.put("FOO", fooType);
}
if (barType!=null && barType.length()>0){
map.put("BAR", barType);
}
由于我有许多键要添加到地图中,因此这种if-checks会使代码变得不漂亮。我想知道是否有任何优雅的方式来做。
我正在将Java 8用于我的项目。
答案 0 :(得分:5)
您可以使用Optional
作为地图的值:
public Map<String,Optional<String>> getMap(){
return ImmutableMap.<String,Optional<String>>builder()
.put("FOO",Optional.<String>ofNullable(getFooType()))
.put("BAR", Optional.<String>ofNullable(getBarType()))
.build();
}
这样地图将存储包裹字符串的可选对象,当您从地图中获取值时,使用map.get(key).orElse(DEF_VALUE);
- 这将为具有空值的那些提供DEF_VALUE。
查看更多here
答案 1 :(得分:2)
重复
if (fooType!=null) {
map.put("FOO", fooType);
}
看起来很冗长,因为它们会被重复。如果你只是将条件add操作放入一个方法并重用它,那么代码看起来就像你的初始非条件代码一样紧凑,因为它包含每个所需映射的一个方法调用。
请注意,您可以轻松地将其与番石榴方法结合使用:
class MyBuilder<K,V> extends ImmutableMap.Builder<K,V> {
public MyBuilder<K, V> putIfValueNotNull(K key, V value) {
if(value!=null) super.put(key, value);
return this;
}
}
...
public Map<String,String> getMap(){
return new MyBuilder<String,String>()
.putIfValueNotNull("FOO",getFooType())
.putIfValueNotNull("BAR", getBarType())
.build();
}
如果您更喜欢这种编码风格,可以将MyBuilder
创建包装到builder()
类型的工厂方法中。
答案 2 :(得分:2)
Pure Java 8解决方案:
public Map<String, String> getMap() {
return Stream.of(
new AbstractMap.SimpleEntry<>("FOO", getFooType()),
new AbstractMap.SimpleEntry<>("BAR", getBarType())
)
.filter(entry -> entry.getValue() != null)
.filter(entry -> !entry.getValue().isEmpty())
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
}