Использование одной хэш-карты против нескольких переменных

#java

#java

Вопрос:

Допустим, у нас есть класс CompHash с 30 различными переменными следующим образом:

    public class CompHash{
      private String abc1;
      private int sdf2;
             :
             :
      private float sgh30;
   }
  

и аналогичный класс:

      public class CompHash{
         private HashMap diffVariables;
     }
  

В ситуации, когда количество переменных, которые мне понадобятся, варьируется от 1 до 30, какая из двух будет лучше?

Комментарии:

1. можете ли вы уточнить больше? как сохранить переменные в hashmap? это должно быть общим? ваш вопрос неясен.

2. diffVariables.put(«abc1», новая строка («привет»));

3. Что это за переменные с загадочными именами? Обычно на языке OO имена ваших классов и имена атрибутов имеют значение, и вы не попадаете в ситуацию, которую вы описываете. Вы просто хотите знать, что требует меньше места для хранения, а что работает быстрее?

4. и тогда как вы планируете использовать эти переменные в другом классе?

5. Кстати, не используйте new String("hello") , "hello" достаточно.

Ответ №1:

В общем, вы всегда должны отдавать предпочтение строго типизированным CompHash (первым). Это не только безопаснее, но и значительно быстрее.

Если у вас есть требование хранить произвольное количество переменных, это HashMap может быть хорошим выбором. Но помните, что вы жертвуете безопасностью типов без особого выигрыша — HashMap вероятно, все равно будет занимать больше памяти, в отличие от одного объекта с большим количеством null s.

Единственное допустимое использование HashMap — это когда вам нужно хранить произвольные пары (неясно, являются ли переменные / имена ключей постоянными в вашем случае) ключ -> значение. Но в этом сценарии я бы рекомендовал оборачивать примитивы иерархией классов, имеющей общего предка, и использовать Visitor шаблон, чтобы избежать опасных выпадений и уродливых instanceof .

Кстати, какую проблему вы на самом деле решаете? Нужная вам структура данных кажется немного экзотической…

Комментарии:

1. ОК. Но что, если количество требуемых переменных слишком велико, и часто используется только небольшая его часть?

2. Я просто пытаюсь найти лучший способ решения проблем, возникающих, когда большую часть времени много переменных не используется. Попытка сохранить размер объекта настолько маленьким, насколько это необходимо.

3. ему может понадобиться типобезопасный гетерогенный контейнер. 🙂

4. Если у вас есть класс с большим количеством переменных, и многие из них не используются, вам, вероятно, нужно перепроектировать свой класс.

5. Если пространство ключей большое, но известное и конечное, большую часть времени я бы использовал поля. Конечно, если пространство ключей очень велико или неизвестно до выполнения (например, класс, представляющий вхождения французских имен ), Map будет лучшей идеей. Класс с десятками (не говоря уже о сотнях или тысячах) полей, в которых всего несколько ненулевых — это катастрофа. Эмпирическое правило: если вы достигли предела размера класса 64K, выберите Map ;-). Также подумайте о своей проблеме, я предполагаю, что вы должны моделировать домен по-другому.

Ответ №2:

Вы также можете рассмотреть List<T> возможность сохранения списка элементов, поскольку вы не уверены, что может быть от 1 до 30 переменных. вы можете использовать динамический массив, то есть: список.

Сохранение объекта в списке — не очень хорошая идея, для его использования потребуется приведение, и если вы не знаете тип, который вы сохранили, вы получите исключение приведения.

Например: если вы хотите сохранить имена учащихся, которые сегодня приходят на занятия, вы можете использовать список. поскольку вы не знаете, сколько учеников появится, вы используете arraylist из-за его динамического характера.

 List<String>
  

это будет ваш код.

Я бы не рекомендовал вам использовать хэш-карту для полей объектов хранилища, в которых будут храниться данные, то есть: свойства.

Комментарии:

1. Вы имеете в виду использовать список с типом object?

Ответ №3:

Если ваш список переменных свойств является известной сущностью, так как в нем будет не более X значений, и я знаю, каким будет тип значения каждого из них, то, безусловно, первый подход будет иметь наибольший смысл. В этой ситуации, как @Tomasz упомянул в своем ответе, предпочтительнее. Вам не придется так сильно беспокоиться о безопасности типов.

Однако, если ваш объект имеет набор свойств, а затем должен иметь список других объектов разных типов и разного количества, тогда хэш-карта может иметь смысл. Есть некоторые вещи, которые следует иметь в виду.

Во-первых, укажите типы как можно лучше. Например:

 HashMap<String,Object> myHash = new HashMap<String, Object>();
  

При создании таким образом ваши ключи hashmap ВСЕГДА должны быть строкой. Если вы имеете дело с вещами, которые называются динамическим образом, это может быть хорошим способом сделать это. Во-вторых, вы заметите, что я указываю только Object. Из-за этого вы можете хранить объекты любого типа, и если вы хотите хранить примитивы, вам нужно будет делать это с ними как Integer , Double, String и т. Д., Вместо int, double, string .

Затем, стрессовая часть такого структурирования заключается в том, что вам нужно будет приводить и проверять типы и быть готовым справиться с этим. Когда вы извлекаете фрагменты информации обратно, вам нужно будет сделать что-то вроде этого:

 if myHash.get(key) instanceof Integer
     Integer myVal = (Integer) myHash.get(key);
else if myHash.get(key) instanceof Double
     Double myVal = (Double) myHash.get(key);
  

Затем вам нужно будет проверять тип и приведение при извлечении значений, а затем отправлять их в новые методы / логику на основе не только имени свойства, но и типа объекта. Есть действительно полезные вещи, которые вы можете выполнить подобным образом … но это может быть трудно сделать, не загоняя себя в слишком сложный угол. Особенно когда Java reflection api можно использовать для динамического получения свойств более безопасным способом (хотя и не без собственных проблем).

Ответ №4:

Мне нравится первый вариант со строго типизированными переменными. НО я настоятельно рассмотрю возможность группировки 30 атрибутов как минимум в 4-5 классов, если это возможно.