Я тренируюсь по использованию Java Steam API и реализовал то, что упоминается в заголовке.
Но я недоволен своим кодом.Объединение объектов сущностей по внешнему ключу с API Java Stream API
Например, существуют три класса сущностей, которые являются простыми неизменяемыми компонентами.
КОД:
public class Country {
private final Integer countryId; // PK, primary key
private final String name;
public Country(Integer countryId, String name) {
this.countryId = countryId;
this.name = name;
}
// omitting getters
}
public class State {
private final Integer stateId; // PK
private final Integer countryId; // FK, foreign key
private final String name;
public State(Integer stateId, Integer countryId, String name) {
this.stateId = stateId;
this.countryId = countryId;
this.name = name;
}
// omitting getters
}
public class City {
private final Integer cityId; // PK
private final Integer stateId; // FK
private final String name;
public City(Integer cityId, Integer stateId, String name) {
this.cityId = cityId;
this.stateId = stateId;
this.name = name;
}
// omitting getters
}
Эти сущности отношение один ко многим, не многие ко многим.
Я хочу создать Map<Country, Map<State, City>>
объект из коллекции сущностей, как Collection<Country>
, Collection<State>
и Collection<City>
с использованием ПК и отношения FK.
Моя реализация здесь.
КОД:
// entity collections
Set<Country> countries = Collections.singleton(new Country(1, "America"));
Set<State> states = Collections.singleton(new State(30, 1, "Wasington"));
Set<City> cities = Collections.singleton(new City(500, 30, "Wasington, D.C."));
// intermediate maps
Map<Integer, City> fkCityMap = cities.stream()
.collect(Collectors.toMap(City::getStateId, Function.identity()));
Map<Integer, State> fkStateMap = states.stream()
.collect(Collectors.toMap(State::getCountryId, Function.identity()));
Map<Integer, Map<State, City>> fkStateCityMap = fkStateMap.entrySet().stream()
.collect(Collectors.toMap(Entry::getKey, entry -> Collections.singletonMap(
entry.getValue(), fkCityMap.get(entry.getValue().getStateId()))));
// result
Map<Country, Map<State, City>> mapWhatIWant = countries.stream()
.collect(Collectors.toMap(Function.identity(),
country -> fkStateCityMap.get(country.getCountryId())));
Он работает, но не элегантно, особенно комментировал "промежуточные карты" часть, я думаю.
Есть ли лучший способ реализовать это?
UPDATE
Есть mistakes mentioned by Holger.
типа, что я хочу
Map<Country, Map<State, Collection<City>>>
,
неMap<Country, Map<State, City>>
.я понял о Вашингтоне и Вашингтоне, округ Колумбия
Таким образом, код комментировал коллекции сущностей является плохим примером.
Во-первых, вы должны переосмыслить свою фактическую задачу. Действительно ли существует сопоставление 1: 1 между «Государством» и «Сити»? – Holger
@ Хольгер Прошу прощения, я не английский динамик. Это неправильное имя. Я обновлю это позже. Спасибо за ваш комментарий. –
@Holger Сопоставление между 'State' и' City' не 1: 1. Это одно для многих **. Итак, введите то, что я хочу, это «Карта <Страна, Карта <Штат, Коллекция >>' как упоминалось ваш комментарий. –