2010-12-31 7 views
3

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

Текущий подход, который я использую, состоит в том, чтобы иметь объект StateList, содержащий HashMap, который хранит State Objects через строковый ключ (т. Е. HashMap < String, State >). Каждый объект состояния содержит свой собственный HashMap City Objects, на который ссылается название города (т. Е. 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; 
    } 
} 

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

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

(Примечание: Edited изменить setPop () и getPop() для setPopulation() и getPopulation() соответственно, чтобы избежать конфуции)

+0

Почему вы не наследуете? – user432209

+0

Ваше решение выглядит разумным. Города - это города, поэтому вполне разумно, чтобы город был атрибутом от 0 до n государства. Кроме того, на решение может повлиять алгоритмическая или производительная проблема, но в вашем случае это не похоже. – RobertB

+1

@ user432209 Унаследовать что? Город не является подклассом государства, он является составным членом. – RobertB

ответ

1

Если вам действительно нужны эти виды агрегации (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

+0

Поскольку я только начинаю, я стараюсь склоняться к более объектно-ориентированному подходу. (Первая трещина, которую я взял на этом, была на другом конце спектра и просто имела HashMap из HashMaps в одном классе.) Я все еще изучаю правила, прежде чем вы нарушаете их часть кривой. Подчеркните свое подтверждение, что мое понимание соответствует основным концепциям. –

1

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

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

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

Спасибо. Я займусь этим. Если я правильно читаю документы, это означает, что на уровне «State» не будет объекта, просто ключ. Хотя это будет охватывать меня прямо сейчас, у меня есть чувство, что мне понадобятся объекты на этом уровне в будущем. Я по-прежнему закладок Multimap, потому что знаю случаи, когда он будет работать отлично. –

+1

Вы можете сохранить объект State как есть и все еще можете использовать его как ключ, переопределив equals(), чтобы проверить равенство на 2 аббревиатура состояния char –

+0

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

0

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

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

+0

Я добавил примечание в исходное сообщение, в конце концов, мне понадобится больше, чем просто население в городе. Итак, я думаю, это указывает на hashMap для хранения каждого в качестве объекта. - Я буду добавлять дополнительную проверку ошибок, когда я продвигаюсь вперед (например, нулевая проверка для объектов City), но я только начинаю на этом этапе. Кроме того, я обновил getPop() и setPop() для getPopulation() и setPopulation() для ясности. Спасибо, что указали на эту путаницу. –

0

Задание «население». Ключевые штрихи дешевы. Вы уже смутили одного ответчика; скорее всего, другие тоже не получат его.

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

+0

отрицательная проверка - лучший вариант использования для слова assert. –

+0

Я обновил исходное сообщение, чтобы изложить полное слово. Согласитесь, что облегчает. У меня есть больше проверок, которые нужно сделать в финальной версии и добавьте отрицательную проверку. Хотел убедиться, что у меня была основная структура, прежде чем я включил все проверки. –