class Home {
String homeName;
String properties;
}
List<Home> list = new ArrayList<>();
list.add(new Home("DefaultHome","other"));
list.add(new Home("MyHome","other"));
list.add(new Home("BigHome","other"));
我想流式传输此列表以查找有效的主属性或返回DefaultHome
属性。
因此,如果我执行以下操作,它应该会返回DefaultHome
属性。
list.stream().filter(a -> a.gethomeName().equals("HomeNotFound")).findFirst();
如果"HomeNotFound"
不在列表中,我应该得到DefaultHome
的Object即new Home("DefaultHome","other")
用OR
添加第二个条件以包含默认值,按名称排序等于DefaultHome
,这样它就一直在末尾:
list.stream().filter(a -> a.getHomeName().equals("HomeNotFound") || a.getHomeName().equals("DefaultHome"))
.sorted(Comparator.comparing(h -> "DefaultHome".equals(h.homeName)))
.findFirst();
方法findFirst()
返回一个可选结果。
正如@Johannes Kuhn在评论中指出的那样,您需要使用Optional.orElse()
:
Home home = list.stream()
.filter(a -> a.getHomeName().equals("someName"))
.findFirst()
.orElse(new Home("DefaultHome","other"));
我想改进@Alexander Ivanchenko的回答,但我还没有足够的声誉来添加评论。
对于常数值和变量,使用orElse
是可以的,但如果将构造函数直接传递给orElse
,则会在调用orElse
方法之前调用该构造函数并实例化新对象。这是因为方法的参数是在调用方法之前解析的。
或者,可以使用orElseGet
,它采用Supplier
函数。只有当Optional
为空时,才会调用此函数。所以,如果我们把亚历山大的答案改写为:
Home home = list.stream()
.filter(a -> a.getHomeName().equals("someName"))
.findFirst()
.orElseGet(() -> new Home("DefaultHome","other"));
,只有在流中未找到匹配项时才会执行构造函数;换句话说,只有在需要的时候。
我想补充一点,如果你想高效地搜索House
的列表,你不应该使用列表,而应该使用Map
:
Map<Home> homeMap = new HashMap<>();
homeMap.put("DefaultHome", new Home("DefaultHome","other"));
homeMap.put("MyHome", new Home("MyHome","other"));
homeMap.put("BigHome", new Home("BigHome","other"));
homeMap.getOrDefault("HomeNotFound", new Home("DefaultHome","other"));
然而,这段代码与Optional.orElse
方法有着相同的问题:无论home是否在地图中,每次都会调用构造函数。一个简单的解决方案是将默认的Home
存储为常量:
public static final String DEFAULT_HOME = new Home("DefaultHome","other")
Map<Home> homeMap = new HashMap<>();
homeMap.put(DEFAULT_HOME.getHomeName(), DEFAULT_HOME);
homeMap.put("MyHome", new Home("MyHome","other"));
homeMap.put("BigHome", new Home("BigHome","other"));
homeMap.getOrDefault("HomeNotFound", DEFAULT_HOME);