简体   繁体   English

Java 中枚举内的 EnumSet 修饰符

[英]EnumSet modifiers inside an enum in Java

It makes sense declaring an EnumSet within a enum with the modifiers static and final ?使用修饰符staticfinal在枚举中声明 EnumSet 是否有意义? Or are redundant?或者是多余的?

Example:例子:

public enum Guitar {
    STRATOCASTER,
    LES_PAUL,
    CLASSIC;

    private static final EnumSet electrics = EnumSet.of(STRATOCASTER, LES_PAUL);
}

Thank you!谢谢!

It makes sense declaring an EnumSet within a enum with the modifiers static and final?使用修饰符 static 和 final 在枚举中声明 EnumSet 是否有意义? Or are redundant?或者是多余的?

No, they are not redundant.不,它们不是多余的。 Consider the following example in which nonElectrics can be set because it's not final .考虑以下示例,其中可以设置nonElectrics ,因为它不是final

import java.util.EnumSet;

enum Guitar {
    STRATOCASTER, LES_PAUL, CLASSIC;

    private static final EnumSet<Guitar> electrics = EnumSet.of(STRATOCASTER, LES_PAUL);
    static EnumSet<Guitar> nonElectrics = EnumSet.of(CLASSIC);

    public static EnumSet<Guitar> getNonElectrics() {
        return nonElectrics;
    }

    public static void setNonElectrics(EnumSet<Guitar> nonElectrics) {
        Guitar.nonElectrics = nonElectrics;
    }

    public static EnumSet<Guitar> getElectrics() {
        return electrics;
    }

    public boolean isElectronics() {
        return electrics.contains(this);
    }
}

public class Main {
    public static void main(String[] args) {
        System.out.println(Guitar.STRATOCASTER.isElectronics());
        System.out.println(Guitar.CLASSIC.isElectronics());
        EnumSet<Guitar> electrics = EnumSet.of(Guitar.STRATOCASTER, Guitar.LES_PAUL);
        Guitar.setNonElectrics(electrics);
        System.out.println(Guitar.getNonElectrics());
    }
}

This is not redundant, fields in enum class not static or final.这不是多余的,枚举 class 中的字段不是 static 或最终字段。 But, you can't invoke not static enum's fields from other classes.但是,您不能从其他类调用非 static 枚举字段。

tl;dr tl;博士

static final public Set ELECTRICS = Set.of( STRATOCASTER , LES_PAUL ) ;

Details细节

Regarding your code:关于您的代码:

private static final EnumSet electrics = EnumSet.of(STRATOCASTER, LES_PAUL);

private

As written, no need for private .正如所写,不需要private

If marked private no other code would have access to this set.如果标记为private ,则没有其他代码可以访问此集合。 So it would serve no purpose.所以它没有任何意义。

static

Yes, static is appropriate.是的, static是合适的。 An enum defines a specific number of named instances of its class.枚举定义了其 class 的特定数量的命名实例。 The instantiation happens automatically when the class first loads at runtime.当 class 在运行时首次加载时,实例化会自动发生。 So each enum object is a separate object.所以每个枚举 object 都是一个单独的 object。 No need for each of them to have their own set.不需要他们每个人都有自己的一套。 The set is unchanging, so just define a single instance of that set by marking it static .该集合是不变的,因此只需通过将其标记为static来定义该集合的单个实例。

This makes the syntax more clear as we do not involve any of the enum objects by name.这使得语法更加清晰,因为我们不涉及任何名称的枚举对象。 Example code:示例代码:

Set < Guitar > guitars = Guitar.ELECTRICS ; 

Or:或者:

Guitar.ELECTRICS.stream.forEach( System.out::println ) ;

final

Yes, mark it as final if this set will be unchanging during the entire run of this app.是的,如果此设置在此应用程序的整个运行过程中保持不变,请将其标记为final Marking as final prevents any other set from being assigned to that field.标记为final可防止将任何其他集合分配给该字段。

EnumSetSet枚举集EnumSet Set

Regarding the first EnumSet , make that simply Set .关于第一个EnumSet ,简单地设置为Set

Generally better to promise a more general superclass or interface rather than lock yourself into a specific concrete class.一般来说,promise 最好是一个更通用的超类或接口,而不是将自己锁定在特定的具体 class 中。

electricsELECTRICS electricsELECTRICS

The name electrics should be in all uppercase, if you intend this set to be fixed, unchanging.如果您打算将此设置固定不变,则名称electrics应全部大写。 Constants in Java are named in all uppercase, by convention.按照惯例,Java 中的常量全部大写。 So, ELECTRICS .所以, ELECTRICS

Plural naming of collection集合的复数命名

Good that you named ELECTRICS in plural.很好,你以复数形式命名了ELECTRICS This name suggests the fact that is a collection rather than a singular enum object.这个名字表明它是一个集合而不是一个单一的枚举 object。

Set.of for unmodifiable collection Set.of用于不可修改的集合

As for the second EnumSet , generally using EnumSet is the right choice for handling enum objects.至于第二个EnumSet ,一般使用EnumSet是处理枚举对象的正确选择。 The EnumSet class is highly optimized for enums, resulting in very fast performance while using very little memory. EnumSet class 针对枚举进行了高度优化,从而在使用非常少的 memory 的同时实现非常快的性能。

But the problem here is that EnumSet is mutable.但这里的问题是EnumSet是可变的。 I expect you do not want any errant code to be adding or removing elements from your set.我希望您不希望任何错误的代码从您的集合中添加或删除元素。

So we want an immutable collection there.所以我们想要一个不可变的集合。 Java provides an unmodifiable set via the Set.of… methods. Java 通过Set.of…方法提供了一个不可修改的集合

Under the covers, those methods are free to use any concrete class they want, and so are free to optimize in the choice of underlying class.在幕后,这些方法可以自由使用他们想要的任何具体 class,因此可以自由优化底层 class 的选择。 So you might end up with an efficient concrete class like EnumSet .因此,您最终可能会得到一个有效的具体 class ,例如EnumSet But that is not paramount, as being immuable trumps performance in this situation.但这并不是最重要的,因为在这种情况下,不变性胜过性能。

Solution code解决方案代码

So I would write that code as:所以我会把这段代码写成:

static final public Set ELECTRICS = Set.of( STRATOCASTER , LES_PAUL ) ;

Explicitly immutable collections in third-party library第三方库中显式不可变 collections

An alternative to using Set.of is to add a library to your project that provides immutability as an explicit part of its collection data types.使用Set.of的另一种方法是向您的项目添加一个库,该库提供不变性作为其集合数据类型的显式部分。 Perhaps Eclipse Collections or Google Guava .也许Eclipse CollectionsGoogle Guava

As for redundancy, see correct Answer by Live and Let Live .至于冗余,请参阅Live 和 Let Live 的正确答案

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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