Жесткий переключатель Java vs hashmap

Некоторые классы сообщений могут возвращать имя тега на основе номера тега

Поскольку этот класс несколько раз подкрепляется, я немного неохотно создаю HashMap для каждого экземпляра:

public class Message {
  private HashMap<Integer,String> tagMap;

  public Message() {
    this.tagMap = new HashMap<Integer,String>();
    this.tagMap.put( 1, "tag1Name");
    this.tagMap.put( 2, "tag2Name");
    this.tagMap.put( 3, "tag3Name");
  }

  public String getTagName( int tagNumber) {
    return this.tagMap.get( tagNumber);
  }
}

В пользу hardcoding:

public class Message {
  public Message() {
  }

  public String getTagName( int tagNumber) {
    switch( tagNumber) {
      case 1: return "tag1Name";
      case 2: return "tag2Name";
      case 3: return "tag3Name";
      default return null;
    }
  }
}

Когда вы помещаете все в микс (Memory, Performance, GC,...)

Есть ли причина придерживаться HashMap?

Ответ 1

Инициализировать MAP в статическом блоке.

И так как вы будете создавать много объектов Message.you должен написать код, подобный этому

public class Message {

  private static HashMap tagMap;

  static {
     tagMap = new HashMap();
     tagMap.put( 1, "tag1Name");
     tagMap.put( 2, "tag2Name");
     tagMap.put( 3, "tag3Name");
  }

  public Message() {

  }

  public String getTagName( int tagNumber) {
    return tagMap.get( tagNumber);
  }
}

Ответ 2

Карта может использоваться как шаблон команды, в которой ключ представляет условие, а значение представляет собой команду, которая должна выполняться, единственный недостаток - это создание объекта перед использованием, поэтому, если у вас есть большое количество таких условий, тогда вы можете выбрать map else switch всегда элегантный подход, если ваших условий мало.

Ответ 3

Зависит от того, что вам нужно. Например, если вам когда-либо понадобилось, чтобы все имена тегов для отображения с помощью Map окупились. Кроме того, если вы заменили на TreeMap, вы можете отсортировать их.
Если у вас нет такой потребности, то использование Map будет накладными расходами, а ваш подход или Enum будет намного более эффективным (у вас будет меньше читаемости, чем у вас вариант 5-10-20 case)

Ответ 4

Почему бы не сделать метод getTagName статическим и ленивым загрузить его из файла свойств?

public static String getTagName(int tagNumber) {
    if tagsByID == null) {
        // load tags from properties
    }
    return tagsByID.get(tagNumber);
}

Простота тестирования и настройки без перекомпиляции.

Ответ 5

Если все ваши значения тегов являются последовательными в интервале [1..n], вы можете использовать массив или, возможно, ArrayList и иметь прямой доступ к значениям.

public class Message {
    private ArrayList<String> tags;

    public Message() {
        this.tags =  = new ArrayList<String>();
        this.tags.add("Unknown");
        this.tags.add("tag1Name");
        this.tags.add("tag2Name");
        this.tags.add("tag3Name");
    }

    public String getTagName(int tagNumber) {
        return this.tags.get(tagNumber);
    }
}

Альтернатива с массивом.

public class Message {
    private static final String[] tags = {
        "N/A",
        "tag1Name",
        "tag2Name",
        "tag3Name",
        null,
        null,
        "tag6Name",
    };

    public Message() {
    }


    public String getTagName(int tagNumber) {
        if (tagNumber < 0 || tagNumber > tags.length) {
            throw new IllegalArgumentException();
        return tags[tagNumber];
    }
}