我想使用Java 8,如何在java 8 Optional中将这种命令式样式设置为功能样式?
例如,假设 exchange.getIn()。getBody()可能为null。
public class Section1 : ConfigurationSection
{
public const string SectionName = "Section1";
private const string FieldDefinitionsCollectionName = "Section1FieldDefinitions";
[ConfigurationProperty(FieldDefinitionsCollectionName)]
[ConfigurationCollection(typeof(Section1Collection),
AddItemName = "add",
ClearItemsName = "clear",
RemoveItemName = "remove")]
public Section1 Items
{
get
{
return (Section1Collection)base[FieldDefinitionsCollectionName];
}
}
}
public class Section1Collection : ConfigurationElementCollection
{
public Section1Collection()
{
}
public Section1FieldDefinitionsElement this[int index]
{
get
{
return (Section1FieldDefinitionsElement)BaseGet(index);
}
set
{
if (BaseGet(index) != null)
{
BaseRemoveAt(index);
}
BaseAdd(index, value);
}
}
public void Add(SectionFieldDefinitionsElement pSection1)
{
BaseAdd(pSection1);
}
public void Clear()
{
BaseClear();
}
protected override ConfigurationElement CreateNewElement()
{
return new Section1FieldDefinitionsElement();
}
protected override object GetElementKey(ConfigurationElement element)
{
return ((Section1FieldDefinitionsElement)element).ID;
}
public void Remove(Section1FieldDefinitionsElement pSection1)
{
BaseRemove(pSection1.ID);
}
public void Remove(string name)
{
BaseRemove(name);
}
public void RemoveAt(int index)
{
BaseRemoveAt(index);
}
}
public class Section1FieldDefinitionsElement : ConfigurationElement
{
[ConfigurationProperty("id", IsRequired = true)]
public string ID
{
get
{
return (string)this["id"];
}
set
{
this["id"] = value;
}
}
[ConfigurationProperty("project", IsRequired = true)]
public string Project
{
get
{
return (string)this["project"];
}
set
{
this["project"] = value;
}
}
[ConfigurationProperty("browsername", IsRequired = true)]
public string Browsername
{
get
{
return (string)this["browsername"];
}
set
{
this["browsername"] = value;
}
}
}
也许这样的事情,但我需要它在一个班轮。
String color = null;
if(exchange.getIn().getBody() instanceof Foo) {
color = "toFoo";
} else if(exchange.getIn().getBody() instanceof Bar){
color = "toBar";
}
我的问题是地图已经是一个字符串,所以我无法将其作为一个字符串:
Optional.ofNullable(exchange.getIn().getBody())
.filter(body -> body instanceof Foo)
.map(body -> "toFoo");
答案 0 :(得分:3)
你想要做的是模式匹配,这不是Optional
的用途。您可以滥用Optional
来获得产生所需结果的内容,例如
Object o=exchange.getIn().getBody();
String color=Optional.ofNullable(o).filter(Foo.class::isInstance).map(x->"toFoo")
.orElseGet(()->Optional.ofNullable(o).filter(Bar.class::isInstance).map(x->"toBar")
.orElse("fallback"));
但这显然不是真正的胜利,特别是如果你考虑将会发生什么,当你添加更多的案例时。
实现目标的一种方法是通过Map
:
Map<Predicate<Object>,String> alternatives=new HashMap<>();
alternatives.put(Bar.class::isInstance, "toBar");
alternatives.put(Foo.class::isInstance, "toFoo");
Object o=exchange.getIn().getBody();
String color=alternatives.entrySet().stream()
.filter(e->e.getKey().test(o))
.findAny().map(Map.Entry::getValue).orElse("fallback");
这执行线性搜索(没有特定顺序,因此谓词必须是析取的),这适用于少数情况,并且您可以添加另一个简单的案例
alternatives.put(Baz.class::isInstance, "toBaz");
但是对于大量的情况,以允许有效查找的方式编码谓词(例如,使用类作为映射键并动态添加遇到的子类)是可取的。
请注意,上面的两个示例使用"fallback"
作为未满足谓词的情况的值。您只需将其替换为null
即可获得与问题代码相同的后备结果。
答案 1 :(得分:1)
为了得到你的单行,我会转过来#34;类似的逻辑:
Object body = exchange.getIn().getBody();
Stream.of(
new Pair<Class, String>(Foo.class, "toFoo"),
new Pair<Class, String>(Bar.class, "toBar"))
.filter(pair -> body != null && body.getClass().isAssignableFrom(pair.getKey())))
.findFirst()
.map(Pair::getValue)
.orElse("default");