我刚刚开始使用Java,我正在寻找有关存储嵌套数据集的好方法的建议。例如,我有兴趣存储可以通过在给定状态下查找城市来访问的城市人口数据。 (注意:最终,其他数据也将与每个城市一起存储,这只是入门的第一次尝试。)
我正在使用的当前方法是拥有一个StateList对象,该对象包含一个HashMap,它通过字符串键存储状态对象(即HashMap< String,State>)。每个状态对象包含其自己的城市对象的HashMap,该城市对象以城市名称为键(即HashMap< String,City>)。
我提出的一个简化版本看起来像这样:
// TestPopulation.java
public class TestPopulation {
public static void main(String [] args) {
// build the stateList Object
StateList sl = new StateList();
// get a test state
State stateAl = sl.getState("AL");
// make sure it's there.
if(stateAl != null) {
// add a city
stateAl.addCity("Abbeville");
// now grab the city
City cityAbbevilleAl = stateAl.getCity("Abbeville");
cityAbbevilleAl.setPopulation(2987);
System.out.print("The city has a pop of: ");
System.out.println(Integer.toString(cityAbbevilleAl.getPopulation()));
}
// otherwise, print an error
else {
System.out.println("That was an invalid state");
}
}
}
// StateList.java
import java.util.*;
public class StateList {
// define hash map to hold the states
private HashMap<String, State> theStates = new HashMap<String, State>();
// setup constructor that loads the states
public StateList() {
String[] stateCodes = {"AL","AK","AZ","AR","CA","CO"}; // etc...
for (String s : stateCodes) {
State newState = new State(s);
theStates.put(s, newState);
}
}
// define method for getting a state
public State getState(String stateCode) {
if(theStates.containsKey(stateCode)) {
return theStates.get(stateCode);
}
else {
return null;
}
}
}
// State.java
import java.util.*;
public class State {
// Setup the state code
String stateCode;
// HashMap for cities
HashMap<String, City> cities = new HashMap<String, City>();
// define the constructor
public State(String newStateCode) {
System.out.println("Creating State: " + newStateCode);
stateCode = newStateCode;
}
// define the method for adding a city
public void addCity(String newCityName) {
City newCityObj = new City(newCityName);
cities.put(newCityName, newCityObj);
}
// define the method for getting a city
public City getCity(String cityName) {
if(cities.containsKey(cityName)) {
return cities.get(cityName);
}
else {
return null;
}
}
}
// City.java
public class City {
// Define the instance vars
String cityName;
int cityPop;
// setup the constructor
public City(String newCityName) {
cityName = newCityName;
System.out.println("Created City: " + newCityName);
}
public void setPopulation(int newPop) {
cityPop = newPop;
}
public int getPopulation() {
return cityPop;
}
}
这对我有用,但我想知道是否有我没有遇到过的问题,或者是否有其他/更好的方法来做同样的事情。
(P.S。我知道我需要添加一些错误检查,但是现在,我专注于尝试找出一个好的数据结构。)
(注意:编辑将setPop()和getPop()分别改为setPopulation()和getPopulation()以避免混淆)
答案 0 :(得分:1)
从guava集合中查看Multimap数据结构。这不是您的解决方案的完整答案,但会简化到一定程度。但美妙的是,现在你可以使用MapMaker来缓存你对城市的“人口问题”。
Multimap<String, City> stateToCities = ArrayListMultimap.create();
stateToCities.put("GA",new City("Atlanta",100000));
stateToCities.put("GA",new City("Cumming",50000));
答案 1 :(得分:1)
如果您确实需要这些类型的聚合(StaleList具有States,具有Cities的州),那么这是正确的实现方式。它可能不是最直接的,但它是最面向对象的方法。因此,对于极简主义的成本,你肯定会获得凝聚力,耦合性,可维护性以及所有那些花哨的软件工程形容词。对于小型项目,不应强制执行这些特征。但对于大型软件项目而言,它们是有意义的并且避免了非常糟糕的代码(但不能保证真正好的代码)。
您还可以使用一些第三方库(如Pangea答案中的那个)来帮助保持代码简单。
请参阅:
1:http://en.wikipedia.org/wiki/Cohesion_(computer_science)
答案 2 :(得分:0)
我会考虑使用一个类来管理包含City和二维数组中的成员变量的列表States
。
其他想法:
未cityAbbevilleAl
检查null
。
起初,我误读了getPop
作为流行方法,而不是人口。
答案 3 :(得分:0)
拼出“人口”。击球很便宜。你已经在这里混淆了一个响应者;也许其他人一开始也不会得到它。
人口可以消极吗?如果没有,我会在你的合同中检查setPopulation()。