4

这似乎是一个常见问题,但建议框中的所有项目都没有准确解释我的疑惑。在这个链接中,每个人都建议使用枚举类型(我现在已经研究过,但之前从未使用过)。我正要建议简单地使用 HashMap 并阅读答案以查看 Enum ( http://docs.oracle.com/javase/tutorial/java/javaOO/enum.html ) 实际上是否是一个更好的答案。根据 oracle 上的链接,“您应该在需要表示一组固定常量的任何时候使用枚举类型。” 所以,是的。

我的问题是……为什么?是不是更多的是形成一个他们不会改变的合同?这是获得某些类功能的更短的方法吗?表现如何?为什么这与在同一个类中定义常量有什么不同?

谢谢!

4

6 回答 6

5

类型安全确实是一个很好的理由:当您将 String 传递给方法时,它可以是任何东西。如果你传递一个枚举,你确定它是合法值之一。如果可能性有限,枚举是好的。如果您需要扩展值,则 HashMaps 很好。

于 2012-12-14T17:19:34.887 回答
4

枚举实例是对象,就像任何其他对象一样封装数据和行为。通过传递枚举实例,任何人都可以调用它的方法。例如,如果您将 Map 键作为字符串传递,则您无法对键执行任何有用的操作。此外,代码的类型安全性和自文档化程度较低,因为 String 很可能与应有的完全不同。

什么是最易读的?

public int countDays(Set<Month> months, int year) {
    int count = 0;
    for (Month month : months) {
        count += month.getDays(year);
    }
    return count;
}

或者

public int countDays(Set<String> months, int year) {
    int count = 0;
    for (String month : months) {
        int days = monthMap.get(month);
        if (month.equals(Months.FEBRUARY)) {
            days = computeDaysInFebruary(year);
        }
        count += days;
    }
    return count;
}

如果我在集合中传递的不是月份名称怎么办?

于 2012-12-14T17:18:03.310 回答
4

枚举是一种非常有限的数据类型,它可以让你将可能的值限制在一个集合中并在编译时避免其他值,所以如果你犯了错误,它甚至不会编译。HashMap 可以让您插入许多无效值,努力在运行时检测到它们,但当然它无论如何都会编译。

于 2012-12-14T17:19:59.993 回答
2

你说的所有理由都非常正确。

枚举更有效,因为它存储为不可变的值列表,并且不必像字典那样支持尽可能多的操作。此外,枚举实例只是在内部存储为单个数字,并且可以像定义自己的“静态最终整数”列表一样使用。

此外,它们增加了类型安全性,因为您不必担心将实际数值与表示某些选项的整数进行比较;枚举只能与其他枚举进行比较。它也不能像字典那样被修改,所以你知道在编译时给出的值在运行时是相同的。

但是,我相信,最重要的原因是它增加了语义价值。这正是枚举的目的——定义一组不变的选项并将自己限制在这些选项中。如果您使用枚举,每个人都将能够直观地理解您正在尝试做什么。

于 2012-12-14T17:18:31.210 回答
2

hashmap 使用大量内存,即使您有恒定的时间查找和插入,仍然需要进行良好的处理。必须计算散列,然后必须解决冲突的插槽等......而枚举通常仅存储在 4 个字节中,是类型安全的,高效,并且对其他程序员来说很明显你正在使用它。

另一个好处是您可以轻松地在枚举值之间使用位算术来表示其他值。Windows API 经常这样做。

于 2012-12-14T17:20:01.040 回答
0

在我看来,它们只是更快地声明和使用,而且,正如 oracle 所说,它们更适合常量。枚举无法修改,所以我猜它们的资源使用量较小。

于 2012-12-14T17:16:18.217 回答