用于存储嵌套项目(例如州中的城市)的良好java数据结构是什么?

发布于 2024-10-10 01:39:27 字数 3156 浏览 0 评论 0原文

我刚刚开始使用 Java,正在寻求有关存储嵌套数据集的好方法的建议。例如,我对存储城市人口数据感兴趣,可以通过查找给定州的城市来访问这些数据。 (注意:最终,其他数据也将存储在每个城市中,这只是第一次尝试。)

我当前使用的方法是拥有一个 StateList 对象,其中包含一个 HashMap,该 HashMap 通过字符串键(即 HashMap)。每个状态对象都包含其自己的与城市名称相关的城市对象的 HashMap(即 HashMap)。

我想出的简化版本如下所示:

// 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;
  }
}

这对我有用,但我想知道是否有我还没有遇到过的问题,或者是否有其他/更好的方法可以做同样的事情。

(PS,我知道我需要添加更多错误检查,但现在,我专注于尝试找出一个好的数据结构。)

(注意:编辑将 setPop() 和 getPop() 更改为 setPopulation( ) 和 getPopulation() 分别以避免混淆)

I'm just getting started in Java and am looking for advice on a good way to store nested sets of data. For example, I'm interested in storing city population data that can be accessed by looking up the city in a given state. (Note: eventually, other data will be stored with each city as well, this is just the first attempt at getting started.)

The current approach I'm using is to have a StateList Object which contains a HashMap that stores State Objects via a string key (i.e. HashMap<String, State>). Each State Object contains its own HashMap of City Objects keyed off the city name (i.e. HashMap<String, City>).

A cut down version of what I've come up with looks like this:

// 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;
  }
}

This is working for me, but I'm wondering if there are gotchas that I haven't run into, or if there are alternate/better ways to do the same thing.

(P.S. I know that I need to add some more error checking in, but right now, I'm focused on trying to figure out a good data structure.)

(NOTE: Edited to change setPop() and getPop() to setPopulation() and getPopulation() respectively to avoid confucsion)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

葵雨 2024-10-17 01:39:27

如果您确实需要这些类型的聚合(具有州的 StaleList、具有城市的州),那么这是正确的实现方法。它可能不是最直接的,但它是最面向对象的方法。因此,以极简主义为代价,您肯定会获得内聚性、耦合性、可维护性以及所有这些花哨的软件工程形容词。对于小型项目,不应强制执行这些特征。但对于大型软件项目来说,它们是有意义的,并且可以避免真正糟糕的代码(但不能保证真正好的代码)。

您还可以使用一些第三方库(例如 Pangea 答案中的库)来帮助保持代码简单。

请参阅:

1:http://en.wikipedia.org/wiki/Cohesion_(computer_science)< /a>

2: http://en.wikipedia.org/wiki/Coupling_(computer_science) 3

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

If you really need these kinds of aggregation (StaleList that have States, States that have Cities), then this is the correct way to implement. It may not be the most straightforward, but it is the most object oriented approach. So, for the cost of minimalism, you sure get cohesion, coupling, maintainability and all those fancy software engineering adjectives. For small projects, these characteristics should not be enforced. But for big software projects they make sense and avoid really bad code (but do not guarantee really good code).

You can also use some third-party libraries (like the one from Pangea answer) to help keeping the code simple.

See:

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

佼人 2024-10-17 01:39:27

查看多图番石榴集合的数据结构。这不是您解决方案的完整答案,但会简化到一定程度。但美妙的是,现在您可以使用 MapMaker 缓存您针对城市的“人口查询”。

Multimap<String, City> stateToCities = ArrayListMultimap.create();

stateToCities.put("GA",new City("Atlanta",100000));
stateToCities.put("GA",new City("Cumming",50000));

Checkout the Multimap data structure from guava collections. This is not the complete answer to your solution but will simplify to certain level. But the beauty is that now you can use MapMaker to cache your "population queries" against the city.

Multimap<String, City> stateToCities = ArrayListMultimap.create();

stateToCities.put("GA",new City("Atlanta",100000));
stateToCities.put("GA",new City("Cumming",50000));
冰葑 2024-10-17 01:39:27

我会考虑使用一个类来管理一个列表 States,其中包含二维数组中的城市和人口成员变量。

其他想法:
cityAbbevilleAl 未针对 null 进行检查。
起初,我将 getPop 误认为是 pop 方法而不是填充方法。

I would consider using one class to manage a list States containing member variables of City and population in two-dimensional arrays.

Other thoughts:
cityAbbevilleAl is not checked against null.
At first, I misread getPop as a pop method and not population.

窗影残 2024-10-17 01:39:27

拼出“人口”。击键很便宜。您已经在这里混淆了一位响应者;其他人一开始也可能不会明白。

人口可以为负数吗?如果没有,我会在您的 setPopulation() 合同中检查这一点。

Spell out "population". Key strokes are cheap. You've already confused one responser here; it's likely that others won't get it at first, either.

Can population be negative? If not, I'd check that in your contract for setPopulation().

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文