【问题标题】:Java Enums IssueJava 枚举问题
【发布时间】:2015-12-29 00:40:57
【问题描述】:

我有一个下面的程序,我的枚举值为“2”,但它并没有按照预期的方式工作。任何帮助将不胜感激。

package com.deepak.streams;

import com.google.common.collect.ImmutableMap;

import java.util.HashMap;
import java.util.Map;

public class Demo2 {

public static void main(String[] args) {
    if (Scores.scoreMap.containsKey("2")) {
        System.out.println("Contains Value");
    } else {
        System.out.println("Does not contains Value");
    }
}

public enum Scores {

    PASS(1), FAIL(2), MATRIC(3), PROMOTED(4);

    private Integer alias;
    private static final Map<Object, Scores> scoreMap;

    Scores(Integer iAlias) {
        alias = iAlias;
    }

    static {
        final Map<Object, Scores> tmpMap = new HashMap<Object, Scores>();
        for(final Scores scores : Scores.values()) {
            tmpMap.put(scores.alias, scores);
            tmpMap.put(scores.name(), scores);
        }
        scoreMap = ImmutableMap.copyOf(tmpMap);
    }

    public Integer getAlias() {
        return alias;
    }

    public static Scores getStudentScoreEnum(Integer intVal) {
        return getScores(intVal);
    }

    public static Scores getStudentScoreEnum(String strVal) {
        return getScores(strVal);
    }

    private static Scores getScores(Object objVal) {
        if(null != objVal && !scoreMap.containsKey(objVal)) {
            throw new IllegalArgumentException("Unknown Value: " + objVal);
        }
        return scoreMap.get(objVal);
    }
}

}

【问题讨论】:

  • 问题不清楚,预期的行为是什么,发生了什么?
  • @Dici - 如果您查看主要方法,我的枚举中显然有键“2”。当我运行它时,它无法显示实际结果,即它没有打印“包含值”。
  • Scores.scoreMap.containsKey(2)
  • 您的枚举中有一个整数键 2,您正在查询字符串值“2”。作为 Integer != String,你得到的结果是正确的和预期的

标签: java enums


【解决方案1】:

您的地图键是Object

    final Map<Object, Scores> tmpMap = new HashMap<Object, Scores>();

这意味着它可以是任何 Java Object。当你使用put 两次时:

    tmpMap.put(scores.alias, scores);
    tmpMap.put(scores.name(), scores);

您的地图现在将包含两个新键。第一个是Integer,因为参数scores.aliasInteger。第二个是String

当您在"2" 上执行查找时,它不会找到Integer 键,因为"2"String,而"2".equals(x)false 的任何x一个String。简单来说,字符串"2" 不等于Integer 2。

如果您确实想使用整数的String 表示作为键来查找键,则在添加到地图时需要使用String 作为键。那就是:

tmpMap.put(scores.alias.toString(), scores); 

最好的办法是将映射声明为具有String 键,而不是Object,这样这样的问题就会在编译时被发现——除非你真的想要能够同时使用 IntegerString 值进行查找。

【讨论】:

  • 他也可以使用 Integer 作为键,这可能是我更喜欢的,这取决于我想要实现的目标
  • 不同意最后一部分。它与地图的类型无关。他只是弄错了scores.name() 的返回值和他定义的别名。这可以与这张地图完美配合,虽然它不是特别优雅。请注意,Map.get 未选中(以Object 作为参数)所以你最后一句话是错误的
  • @Dici 当然错误不是因为地图的类型。但是,尽管他需要创建密钥类型String,但最好是这样做,除非有充分的理由不这样做。我们不知道他在他的完整程序中想要完成什么,但它可能不涉及使用文字 "2" 作为键;他似乎更有可能要求用户输入,并且允许用户输入数字或枚举名称。但我们都只是在这里猜测。
  • @ajb 也许,那只是一个意见。但是关于编译时错误的部分仍然是错误的,因为 Map.get 未被选中
  • @Dici 它会在tmpMap.put() 上捕获一个错误,并将整数作为第一个参数。此外,如果他将密钥类型设为String,他还应该更改getScores 参数的类型。
【解决方案2】:

您的地图包含整数2 的绑定,而不是字符串"2"。名称映射将为"MATRIC" -&gt; enumValue

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多