Java枚举自动递增条目?

发布于 2024-08-17 20:25:46 字数 233 浏览 2 评论 0原文

Java 是否允许像优秀的 C 甚至 C# 那样的东西,因为您可以定义一个带有值自动增长的字段的枚举,并从可选的给定值开始?

例如,

在 C 或 C# 中:

enum Foo { A = 10, B, C, D = 5000, E, Fish };

产量 A = 10、B = 11、C = 12、D = 5000、E = 5001、鱼 = 5002。

Does Java allow something like good ol' C or even C# in the sense that you can define an enum with fields that grow in value automatically, and start at an optionally given value?

E.g.

In C or C#:

enum Foo { A = 10, B, C, D = 5000, E, Fish };

Yields A = 10, B = 11, C = 12, D = 5000, E = 5001, Fish = 5002.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

奶茶白久 2024-08-24 20:25:46

在 Java 中,您根本无法显式指定序数值。根本。它们总是从 0 开始自动递增,且无法控制。

如果您想要其他自定义值,则需要将它们放入构造函数调用中并自行存储。您可以获得自动增量,但这很糟糕:

import java.util.EnumSet;

// Please don't ever use this code. It's here so you can point and laugh.
enum Foo 
{ 
    A(10), B, C, D(5000), E, Fish;

    private static int nextValue;
    private int value;

    private Foo()
    {
        this(Counter.nextValue);
    }

    private Foo(int value)
    {
        this.value = value;
        Counter.nextValue = value + 1;
    }

    public int getValue() 
    {
        return value;
    }

    private static class Counter
    {
        private static int nextValue = 0;
    }
}

public class Test
{
    public static void main(String[] args)
    {
        for (Foo foo : EnumSet.allOf(Foo.class))
        {
            System.out.println(foo.name() + " " + 
                               foo.ordinal() + " " + 
                               foo.getValue());
        }
    }
}

请注意嵌套类的需要,因为您无法访问枚举构造函数中的静态字段。恶心,恶心,恶心。请不要这样做。

In Java you can't specify the ordinal values explicitly at all. They always autoincrement, from 0, with no control over it.

If you want other custom values, you need to put them in constructor calls and store them yourself. You can get autoincrement, but it's icky as heck:

import java.util.EnumSet;

// Please don't ever use this code. It's here so you can point and laugh.
enum Foo 
{ 
    A(10), B, C, D(5000), E, Fish;

    private static int nextValue;
    private int value;

    private Foo()
    {
        this(Counter.nextValue);
    }

    private Foo(int value)
    {
        this.value = value;
        Counter.nextValue = value + 1;
    }

    public int getValue() 
    {
        return value;
    }

    private static class Counter
    {
        private static int nextValue = 0;
    }
}

public class Test
{
    public static void main(String[] args)
    {
        for (Foo foo : EnumSet.allOf(Foo.class))
        {
            System.out.println(foo.name() + " " + 
                               foo.ordinal() + " " + 
                               foo.getValue());
        }
    }
}

Note the need for the nested class, because you can't access static fields within an enum constructor. Ick, ick, ick. Please don't do this.

享受孤独 2024-08-24 20:25:46

这是 Java Enum 的设计选择,不支持更改序数值。基本上,它们不够稳定不足以依赖它们。如果您更改示例客户端中 B 和 C 的位置,则顺序值将被破坏。这可能是无意中发生的。

在《Effective Java》第 31 项:使用实例字段代替序号

您可以以稳定的方式模拟行为:

enum X{
    A(10), B(A), C(B), D(5000), E(D), F(E);

    private final int value;

    X(int value){
        this.value = value;
    }

    X(X preceding){
        this.value = preceding.getValue() + 1;
    }

    public int getValue() {
        return value;
    }

    @Override
    public String toString() {
        return this.name() + "(" + this.value + ")";
    }

    static {
        Set<Integer> values = new HashSet<Integer>();
        for(X x : X.values()) values.add(x.value);
        assert(values.size() == X.values().length); //no duplicates
    }
}

使用此定义,您可以更改值的顺序而不会破坏客户端。

调用 for(X x : X.values()) System.out.println(x); 返回:

A(10)
B(11)
C(12)
D(5000)
E(5001)
F(5002)

This is a design choice of Java Enums to not support to change the ordinal values. Basically, they are not stable enough to depend on them. If you change the position of B and C in your example clients depending on the ordinal values are broken. This may happen unintentionally.

The problem is described in Effective Java Item 31: Use instance field instead of ordinals.

You can emulate the behavior in a stable manner:

enum X{
    A(10), B(A), C(B), D(5000), E(D), F(E);

    private final int value;

    X(int value){
        this.value = value;
    }

    X(X preceding){
        this.value = preceding.getValue() + 1;
    }

    public int getValue() {
        return value;
    }

    @Override
    public String toString() {
        return this.name() + "(" + this.value + ")";
    }

    static {
        Set<Integer> values = new HashSet<Integer>();
        for(X x : X.values()) values.add(x.value);
        assert(values.size() == X.values().length); //no duplicates
    }
}

With this definition you may change the order of the values without breaking clients.

Calling for(X x : X.values()) System.out.println(x); returns:

A(10)
B(11)
C(12)
D(5000)
E(5001)
F(5002)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文