Reputation: 15
I have a complex obj
object that contains a CountryUnit
object that holds a collection of countries
.
countries
has the following countryValue
values:
countries == {
Country1 (countryValue == "A")
Country2 (countryValue == "B")
}
In this case, I need to do a transformation so that the resulting set countries
contains the values for countryValue
which will be replaced with the randomly selected values from allowedCountryList
. For example:
countries == {
Country1 (countryValue == "N")
Country2 (countryValue == "S")
}
Then I need to return the obj
object already with the new values for countryValue
. What's the easiest way to do it? I have a piece of code but it doesn't work as it should.
SomeObject obj; // complex object that contains multiple levels, obj contains CountryUnit object
public class CountryUnit {
private Set<Country> countries = new HashSet<>();
// getters, setters
}
public class Country {
private String countryValue;
// getters, setters
}
My code:
List<String> CountryChecker = Arrays.asList("A", "B", "C");
List<String> allowedCountryList = Arrays.asList("L", "M", "N", "O", "P", "R", "S");
obj.getSomeSet().stream()
.map(CountryUnit::getCountries)
.flatMap(Set::stream)
.filter((x) -> CountryChecker.contains(x.getCountryValue()))
.map(y -> {
Random r = new Random();
int rCountry = r.nextInt(allowedCountryList.size());
y.setCountryValue(allowedCountryList.get(rCountry));
return y;
});
Upvotes: 0
Views: 41
Reputation: 17890
You are almost there. Since you are already updating existing Country
object, use a forEach
rather than a map
operator on the stream.
obj.getSomeSet().stream()
.map(CountryUnit::getCountries)
.flatMap(Set::stream)
.filter((x) -> CountryChecker.contains(x.getCountryValue()))
.forEach(y -> {
Random r = new Random();
int rCountry = r.nextInt(allowedCountryList.size());
y.setCountryValue(allowedCountryList.get(rCountry));
});
And you can combine the map and the flatMap calls as:
obj.getSomeSet().stream()
.flatMap(countryUnit -> countryUnit.getCountries().stream())
.filter(country -> CountryChecker.contains(country.getCountryValue()))
.forEach(country -> {
Random r = new Random();
int rCountry = r.nextInt(allowedCountryList.size());
country.setCountryValue(allowedCountryList.get(rCountry));
});
If you follow Java's naming convention, you should rename variable names to start with a lower-case (countryChecker
or countriesToUpdate
). It would be better if it is a Set
because we call contains
on it. With a set, that will be a constant time operation rather than a linear search.
Upvotes: 1