Java 8 forEach returning property from inner loop
I need to return a property of some object that I need to access from in a loop forEach
. Basically I have an object user
that has a property List<UserLocation>
, and inside the object UserLocation
is an object Location
with a property location_id
. If store_id
in object user
matches store_id
in object UserLocation
, then this is the one I need to get location_id
. However, the problem I am getting is that it says that the variable used inside the lambda expression must be final, or actually final. See code below.
User user = getUser(request);
Integer locationId;
user.getUserLocations().forEach(ul -> {
if (ul.getStoreId() == user.getStoreId()) {
locationId= ul.getUserLocations().getLocationId();
}
});
Any advice or solution would be appreciated!
source to share
The error tells you what the problem is: you cannot assign a closure from within. You can get around this by creating a mutable container, array, or list, but it's better to use the stream findFirst
method:
Optional<Integer> optLocationId = user.getUserLocations().stream()
.filter(ul -> ul.getStoreId() == user.getStoreId())
.findFirst();
if (optLocationId.isPresent()) {
Integer locationId = optLocationId.get().getUserLocations().getLocationId();
}
source to share
This can be done better without forEach
, assuming you only need to find one location:
Integer locationId = user.getUserLocations()
.stream()
.filter(ul -> ul.getStoreId() == user.getStoreId())
.findAny()
.map(ul -> ul.getLocation().getLocationId())
.orElse (0); // default value in case no match is found
PS I guess that ul.getUserLocations()
is a typo and should be ul.getLocation()
, since you wrote that inside the UserLocation object is a Location object
and getUserLocations()
represents a class method User
, not a class UserLocation
.
source to share