简体   繁体   中英

Java hardcoded switch vs hashmap

Some Message class is able to return a tag name based on tag number

Since this class is instanciated many times, I am a bit reluctant to create a HashMap for each instance:

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

In favor of 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;
    }
  }
}

When you put everything in the mix ( Memory, Performance, GC, ...)

Is there any reason to stick to HashMap?

Initialize MAP in a static block.

And since you will be creating many objects of Message.you should write code like this

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

映射可以用作命令模式,其中键表示条件,值表示要执行的命令唯一的缺点是对象在使用之前被创建,因此如果你有大量这样的条件那么你可以选择map else else switch总是优雅的方法如果你的条件很少。

Depends on what you need. For example if you ever needed to get all the tag names for display using a Map would pay off. Additionally if you replaced with a TreeMap you could get them sorted.
If you don't have such a need, then using a Map would be an overhead and your approach or an Enum would be much more efficient (you will have less readability though than you option of 5-10-20 case options)

Why not make the getTagName method static and lazy load it from a properties file?

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

Easy to test and configurable without a recompile.

If all your tag values are consecutive in the interval [1..n] then you can use an array or maybe an ArrayList and have direct access to the values.

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

Alternative with an array.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM