我正在接受使用Java Steam API并实施标题中提到的内容的培训。
但我不满意我的代码。使用Java Stream API通过外键连接实体对象
例如,有三个实体类是简单的不可变bean。
CODE:
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>>
对象使用PK和FK关系 Collection<Country>
,Collection<State>
和Collection<City>
。
我的实现就在这里。
CODE:
// 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>>
。我误解了有关华盛顿和华盛顿
所以,代码注释实体的集合是坏榜样。
首先,你应该重新考虑你的实际任务。 “State”和“City”之间是否存在1:1映射? – Holger
@霍尔格对不起,我不是英语说话的人。这是错误的命名。我会稍后更新。感谢您的评论。 –
@Holger'State'和'City'之间的映射不是1:1。它是**一对多**。所以,键入我想要的是'地图<国家,地图<状态,收集 >>'如上所述您的评论。 –