maaartinus
maaartinus

Reputation: 46412

Can this hacky enum be improved?

For a benchmark, I need three different settings ("keep all", "keep size", and "keep nothing"), so I though I could use an enum. Then I saw that I need to run some of the cases multiple times (the benchmark uses a seeded Random) and my original enum got pretty inflexible. For Caliper, I need to repeat the enum items. After some failed tries to make it properly, I ended up with this hacky idea:

private enum Randomization {
    USE_EXAMPLE_1,
    USE_EXAMPLE_2,
    KEEP_EXAMPLE_SIZE_1,
    RANDOM_1,
    RANDOM_2,
    RANDOM_3,
    ;

    final boolean keepAll;
    final boolean keepSize;

    private Randomization() {
        keepAll = name().startsWith("U");
        keepSize = !name().startsWith("R");
    }
}

It does exactly what I want, I can add or remove experiments with minimum overhead. Is there any nicer solution?

Upvotes: 0

Views: 117

Answers (2)

qqilihq
qqilihq

Reputation: 11454

You can have fields in your enum and do something like the following. Instance methods of the enum can access the fields like in usual classes:

private enum Randomization {
    USE_EXAMPLE_1(1),
    USE_EXAMPLE_2(2),
    // ...

    private final int flag;

    Randomization(int flag) {
        this.flag = flag;
    }
}

This avoids the problem of potential refactorings renaming the values of the enum and doesn't tie you to the name.

Upvotes: 1

Jon Skeet
Jon Skeet

Reputation: 1500335

Is there any nicer solution?

Well, it's not really very clear why you need these repeated enum values in the first place - I suspect I'd have an enum which just included the logical values, and then populate a collection using repeated values instead.

Another option would be to have an enum like the current one, and a more logical enum, where the constructor to the "repetitive" enum takes a reference to an instance of the "logical" one instead.

If you really, really want to keep the current structure, I'd personally ditch the inference of the keepSize and keepAll parts, and use a parameterized constructor instead:

private enum Randomization {
    USE_EXAMPLE_1(true, true),
    USE_EXAMPLE_2(true, true),
    KEEP_EXAMPLE_SIZE_1(false, true),
    RANDOM_1(false, false),
    RANDOM_2(false, false),
    RANDOM_3(false, false),
    ;

    final boolean keepAll;
    final boolean keepSize;

    private Randomization(boolean keepAll, boolean keepSize) {
        this.keepAll = keepAll;
        this.keepSize = keepSize;
    }
}

Upvotes: 1

Related Questions