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"));
I want to stream this list to find valid home properties or return DefaultHome
properties.
So if I do the following, it should return me DefaultHome
properties.
list.stream().filter(a -> a.gethomeName().equals("HomeNotFound")).findFirst();
If "HomeNotFound"
is not in the list, I should get Object of DefaultHome
which is new Home("DefaultHome","other")
CodePudding user response:
Method findFirst()
returns an Optional result.
You need to use Optional.orElse()
as @Johannes Kuhn has pointed out in the comments:
Home home = list.stream()
.filter(a -> a.getHomeName().equals("someName"))
.findFirst()
.orElse(new Home("DefaultHome","other"));
CodePudding user response:
Add with an OR
a second condition to include your default value, sort by name equals DefaultHome
so that it is allways at the end:
list.stream().filter(a -> a.getHomeName().equals("HomeNotFound") || a.getHomeName().equals("DefaultHome"))
.sorted(Comparator.comparing(h -> "DefaultHome".equals(h.homeName)))
.findFirst();
CodePudding user response:
I'd like to improve on @Alexander Ivanchenko's answer, but I don't have enough reputation to add comments yet.
Using orElse
is fine for constant values and variables, but if you pass a constructor directly to orElse
will call the constructor and instantiate a new object before the orElse
method is called. This is because the arguments to methods are resolved before the methods are called.
Alternatively, one could use orElseGet
, which takes a Supplier
function. This function is only called if the Optional
is empty. So, if we rewrite Alexander's answer as this:
Home home = list.stream()
.filter(a -> a.getHomeName().equals("someName"))
.findFirst()
.orElseGet(() -> new Home("DefaultHome","other"));
, the constructor will only be executed when no match was found in the stream; in other words, only when it is needed.
I'd like to add that if you want to search through a list of House
s efficiently, you should not use a list, but a 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"));
This code, however, has the same problem as the Optional.orElse
method: the constructor is called every time, regardless the home is in the map or not. A simple solution for this is to store the default Home
as a constant:
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);