什么是用于存储嵌套项目(如状态中的城市)的优秀Java数据结构?

时间:2010-12-31 20:01:02

标签: java data-structures object

我刚刚开始使用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()以避免混淆)

4 个答案:

答案 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:http://en.wikipedia.org/wiki/Coupling_(computer_science)

3:http://en.wikipedia.org/wiki/Maintainability

答案 2 :(得分:0)

我会考虑使用一个类来管理包含City和二维数组中的成员变量的列表States

其他想法: 未cityAbbevilleAl检查null。 起初,我误读了getPop作为流行方法,而不是人口。

答案 3 :(得分:0)

拼出“人口”。击球很便宜。你已经在这里混淆了一个响应者;也许其他人一开始也不会得到它。

人口可以消极吗?如果没有,我会在你的合同中检查setPopulation()。