如何用从列表中提取的值替换集合的指示值

How to replace the indicated values ​of a set with values ​drawn from the list

我有一个复杂的 obj 对象,其中包含一个包含 countries 集合的 CountryUnit 对象。 countries 具有以下 countryValue 值:

countries == {
                Country1 (countryValue == "A")
                Country2 (countryValue == "B")
             }

在这种情况下,我需要进行转换,以便结果集 countries 包含 countryValue 的值,这些值将替换为从 allowedCountryList 中随机选择的值。例如:

countries == {
                Country1 (countryValue == "N")
                Country2 (countryValue == "S")
             }

然后我需要 return obj 对象已经具有 countryValue 的新值。最简单的方法是什么?我有一段代码,但它无法正常工作。

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
}

我的代码:

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;
                    });

你快到了。由于您已经在更新现有的 Country 对象,因此在流上使用 forEach 而不是 map 运算符。

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));
            });

您可以将地图和 flatMap 调用组合为:

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));
            });

如果您遵循 Java 的命名约定,您应该将变量名重命名为以小写开头(countryCheckercountriesToUpdate)。如果它是 Set 会更好,因为我们在其上调用 contains。对于集合,这将是一个常数时间操作而不是线性搜索。