Что такое хорошая структура данных Java для хранения вложенных элементов (например, городов в штатах)? - PullRequest
3 голосов
/ 31 декабря 2010

Я только начинаю работать с Java и ищу совет относительно хорошего способа хранения вложенных наборов данных. Например, я заинтересован в хранении данных о населении города, к которым можно обратиться, выполнив поиск города в данном штате. (Примечание: в конце концов, другие данные будут храниться вместе с каждым городом, это только первая попытка начать работу.)

Текущий подход, который я использую, состоит в том, чтобы иметь объект StateList, который содержит 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;
  }
}

Это работает для меня, но мне интересно, есть ли ошибки, с которыми я не сталкивался, или есть альтернативные / лучшие способы сделать то же самое.

(П.С. Я знаю, что мне нужно добавить еще одну проверку ошибок, но сейчас я сосредоточен на попытке выяснить хорошую структуру данных.)

(ПРИМЕЧАНИЕ. Отредактировано для изменения setPop () и getPop () на setPopulation () и getPopulation () соответственно, чтобы избежать путаницы)

Ответы [ 4 ]

1 голос
/ 31 декабря 2010

Если вам действительно нужны такие виды агрегации (StaleList, в котором есть государства, государства, в которых есть города), то это правильный способ реализации. Это может быть не самым простым, но это наиболее объектно-ориентированный подход. Таким образом, за счет минимализма, вы наверняка получите сплоченность, связь, ремонтопригодность и все эти причудливые прилагательные разработки программного обеспечения. Для небольших проектов эти характеристики не должны применяться. Но для больших программных проектов они имеют смысл и избегают действительно плохого кода (но не гарантируют действительно хороший код).

Вы также можете использовать некоторые сторонние библиотеки (например, из ответа 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

1 голос
/ 31 декабря 2010

Извлечение структуры данных Multimap из коллекций гуавы.Это не полный ответ на ваше решение, но упростит до определенного уровня.Но прелесть в том, что теперь вы можете использовать MapMaker для кэширования ваших «запросов населения» по городу.

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

stateToCities.put("GA",new City("Atlanta",100000));
stateToCities.put("GA",new City("Cumming",50000));
0 голосов
/ 31 декабря 2010

Разобрать "население". Клавиши дешево. Вы уже запутали одного респондента здесь; Вполне вероятно, что и другие сначала не получат его.

Может ли население быть отрицательным? Если нет, я бы проверил это в вашем контракте на setPopulation ().

0 голосов
/ 31 декабря 2010

Я хотел бы рассмотреть возможность использования одного класса для управления списком States, содержащим переменные-члены City и населения в двумерных массивах.

Другие соображения: cityAbbevilleAl не проверяется на null.Сначала я неправильно прочитал getPop как популярный метод, а не как популяцию.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...