我有一个唯一的位置对象集,其数据如
location 1: "USA", "AZ", "Phoenix"
location 2: "USA", "AZ", "Scottsdale"
location 3: "USA", "AZ", "Peoria"
Front end needs following json structure to render UI:
"USA"-> [{"AZ" -> ["Phoenix", "Scottsdale","Peoria"]},
{"MD" -> ["Baltimore", "Gaithersburg","OwingsMills"]}
]
Location.java的Java POJO
我编写了几行代码,以循环访问位置集,并使用FacetsGeo对象构造包含状态对象集的国家对象,其中包含状态对象的集包含城市对象的集,并从此数据模型中生成json。
我在想,可能有更好的方法:可能使用Java 8 Streaming API。
正如我在上面所说的那样,任何帮助表示赞赏的是示例数据如何构建平坦的位置。
public class Location {
private final String country;
private final String state;
private final String city;
public Location(final String country, final String state, final
String city) {
this.country = country;
this.state = state;
this.city = city;
}
public String getCountry() {
return country;
}
public String getState() {
return state;
}
public String getCity() {
return city;
}
@Override
public boolean equals(Object thatLocation) {
if (thatLocation == this) return true;
if (!(thatLocationCriteria instanceof Location)) {
return false;
}
Location location = (Location) thatLocation;
return Objects.equals(this.country, location.country) &&
Objects.equals(this.state, location.state) &&
Objects.equals(this.city, location.city);
}
@Override
public int hashCode() {
return Objects.hash(this.country, this.state, this.city);
}
}
FacetsGeo.java
public class FacetsGeo {
private String label;
private String value;
private String type;
private String subtype;
private List<FacetsGeo> childFacetsGeo;
}
我试图在前端数据结构上方生成的内容:
` List<FacetsGeo> facetsList = new ArrayList<FacetsGeo>();
Optional<locations> locationsOptional = Optional.ofNullable(locations);
if(locationsOptional.isPresent()) {
//locations
for (final Location location : locationsOptional.get().getLocations()) {
FacetsGeo facetCountry = new FacetsGeo();
if(location.getCountry() != null
&& location.getCountry().equalsIgnoreCase("United States")
&& location.getState() != null) {
boolean countryExists = false;
for(FacetsGeo facetGeo: facetsList) {
if(facetGeo.getType() != null && facetGeo.getSubtype() != null
&& facetGeo.getType().equalsIgnoreCase("location")
&& facetGeo.getSubtype().equalsIgnoreCase("country")
&& facetGeo.getValue().equalsIgnoreCase(location.getCountry())) {
facetCountry = facetGeo;
if(facetCountry.getSubCriteria() == null) {
facetCountry.setSubCriteria(new ArrayList<FacetsGeo>());
}
countryExists = true;
break;
}
}
if(!countryExists) {
facetCountry.setLabel(location.getCountry());
facetCountry.setValue(location.getCountry());
facetCountry.setType("location");
facetCountry.setSubtype("country");
FacetsGeo subcriteriaState = new FacetsGeo();
subcriteriaState.setLabel(location.getState());
subcriteriaState.setValue(location.getState());
subcriteriaState.setType("location");
subcriteriaState.setSubtype("state");
FacetsGeo subcriteria = new FacetsGeo();
subcriteria.setLabel(location.getCity());
subcriteria.setValue(location.getCity());
subcriteria.setType("location");
subcriteria.setSubtype("city");
subcriteriaState.setSubCriteria(new ArrayList<FacetsGeo>());
subcriteriaState.getSubCriteria().add(subcriteria);
facetCountry.setSubCriteria(new ArrayList<FacetsGeo>());
facetCountry.getSubCriteria().add(subcriteriaState);
searchBarFacetsList.add(searchBarFacetCountry);
} else {
FacetsGeo subcriteriaCity = new FacetsGeo();
subcriteriaCity.setLabel(location.getCity());
subcriteriaCity.setValue(location.getCity());
subcriteriaCity.setType("location");
subcriteriaCity.setSubtype("city");
FacetsGeo facetStateToAdd = new FacetsGeo();
boolean stateExists = false;
for(FacetsGeo facetState: facetCountry.getSubCriteria()) {
if(facetState.getType() != null && facetState.getSubtype() != null
&& facetState.getType().equalsIgnoreCase("location")
&& facetState.getSubtype().equalsIgnoreCase("state")
&& facetState.getValue().equalsIgnoreCase(location.getState())) {
facetStateToAdd = facetState;
if(facetStateToAdd.getSubCriteria() == null) {
facetStateToAdd.setSubCriteria(new ArrayList<FacetsGeo>());
}
stateExists = true;
break;
}
}
if(!stateExists) {
facetStateToAdd.setLabel(location.getState());
facetStateToAdd.setValue(location.getState());
facetStateToAdd.setType("location");
facetStateToAdd.setSubtype("state");
if(facetStateToAdd.getSubCriteria() == null) {
facetStateToAdd.setSubCriteria(new ArrayList<SearchBarFacets>());
}
facetStateToAdd.getSubCriteria().add(subcriteriaCity);
facetCountry.getSubCriteria().add(facetStateToAdd);
} else {
facetStateToAdd.getSubCriteria().add(subcriteriaCity);
facetCountry.getSubCriteria().add(facetStateToAdd);
}
}
}
}
}`
答案 0 :(得分:5)
对于Java 8流解决方案,可以按以下方式完成。
此特定解决方案不会生成与问题中显示的JSON完全相同的JSON,因为我认为状态对象数组(每个对象为状态命名一个键)不是一个好的JSON结构。
如果JSON必须类似于问题中所示,那么此解决方案将为您提供一个良好的开端。
Set<Location> locationSet = Set.of(
new Location("USA", "AZ", "Phoenix"),
new Location("USA", "AZ", "Scottsdale"),
new Location("USA", "AZ", "Peoria"),
new Location("USA", "MD", "Baltimore"),
new Location("USA", "MD", "Gaithersburg"),
new Location("USA", "MD", "OwingsMills"),
new Location("CA", "ON", "Toronto"));
Map<String, Map<String, List<String>>> countryMap = locationSet.stream()
.collect(Collectors.groupingBy(Location::getCountry, TreeMap::new,
Collectors.groupingBy(Location::getState, TreeMap::new,
Collectors.mapping(Location::getCity, Collectors.toList()))));
System.out.println(JSONWriter.valueToString(countryMap));
输出
{"CA":{"ON":["Toronto"]},"USA":{"AZ":["Phoenix","Scottsdale","Peoria"],"MD":["OwingsMills","Baltimore","Gaithersburg"]}}