标签: enumset

EnumSet序列化

我刚刚失去了几个小时调试我的应用程序,我相信我偶然发现了一个(另一个o_O)Java bug ...嗅...我希望它不是,因为这会很难过:(

我正在做以下事情:

  1. mask使用一些标志创建EnumSet
  2. 序列化(带ObjectOutputStream.writeObject(mask))
  3. 清除并设置其中的一些其他标志 mask
  4. 再次序列化

预期结果:第二个序列化对象与第一个序列化对象不同(反映实例中的更改)

获得的结果:第二个序列化对象是第一个的精确副本

代码:

enum MyEnum {
    ONE, TWO
}

@Test
public void testEnumSetSerialize() throws Exception {           
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    ObjectOutputStream stream = new ObjectOutputStream(bos);

    EnumSet<MyEnum> mask = EnumSet.noneOf(MyEnum.class);
    mask.add(MyEnum.ONE);
    mask.add(MyEnum.TWO);
    System.out.println("First serialization: " + mask);
    stream.writeObject(mask);

    mask.clear();
    System.out.println("Second serialization: " + mask);
    stream.writeObject(mask);
    stream.close();

    ObjectInputStream istream = new ObjectInputStream(new ByteArrayInputStream(bos.toByteArray()));

    System.out.println("First deserialized " + istream.readObject());
    System.out.println("Second deserialized " + istream.readObject());
}
Run Code Online (Sandbox Code Playgroud)

它打印:

First serialization: …
Run Code Online (Sandbox Code Playgroud)

java serialization enumset

9
推荐指数
1
解决办法
1075
查看次数

在Java方法中使用标志的最佳实践

在Java方法中指定标志的最佳做法是什么?

我已经看到SWT使用int作为位域,如:

(部分来自"Effective Java,2nd Ed."第159页):

public class Text {
  public static final int STYLE_BOLD = 1 << 0; // 1
  public static final int STYLE_ITALIC = 1 << 1; // 2

  void printText(String text, int flags) {

  }
}
Run Code Online (Sandbox Code Playgroud)

你的客户电话看起来像:

printText("hello", Text.STYLE_BOLD | Text.STYLE_ITALIC);
Run Code Online (Sandbox Code Playgroud)

..但是这是不鼓励的,因为你可以将来自不同类的标志(int值)混合在一起,而无需任何编译器检查.

在同一本书("Effective Java")中,我看到了EnumSet的使用,但随后您的用户调用变为:

printText("hello", EnumSet.of(Style.Bold, Style.ITALIC));
Run Code Online (Sandbox Code Playgroud)

我发现这有点冗长,我更喜欢SWT的优雅.

还有其他选择还是这基本上是你必须选择的两种口味?

java flags swt enumset

8
推荐指数
1
解决办法
1万
查看次数

Java - EnumSet.add(枚举),抛出NullPointerException

这是Java,跨平台,并在运行Ubuntu Oneric的计算机上进行调试,OpenJDK作为我的运行时安装.

我有一个EnumSet用于检查我正在进行的游戏中的类内部.我有来自logcat的读数,来自我的构造函数中的debug aplenty:

Tile : passability being set...?
Exception in thread "Thread-1" javax.media.opengl.GLException:java.lang.NullPointerException
    ...
Caused by: java.lang.NullPointerException
    at net.darkglass.map.Tile.addPassability(Tile.java:144)
    ...
Run Code Online (Sandbox Code Playgroud)

不好笑.跟踪它,我的问题似乎完全是这条线:

public void addPassability(Passability type)
{
    this.passability.add(type);
}
Run Code Online (Sandbox Code Playgroud)

我指的是那个功能的主体.它从构造函数中调用为:

this.addPassability(Passability.AIR);
Run Code Online (Sandbox Code Playgroud)

发生NullPointerException时.在Passability Enum Type的主体中,我有

public enum Passability
{
    AIR, ALL, GROUND, NONE, SIGHT, SKILL, STRUCTURE, WATER;
}
Run Code Online (Sandbox Code Playgroud)

就字面意思而言,整个枚举保存包声明.this.passability已声明

private EnumSet <Passability> passability;
Run Code Online (Sandbox Code Playgroud)

在类定义的开头,我的印象是add()方法作为Java标准中EnumSet定义的一部分继承.

我是自学成才,但我并不疯狂.要么我有错误,要么有更好的方法来做到这一点.那些有一些有用知识的人能够伸出援手吗?

java enums nullpointerexception enumset

8
推荐指数
1
解决办法
7089
查看次数

启用EnumSet

旧的方式,如果我们想要switch一些复杂的位掩码,我们可以很容易地这样做(从我头顶的一个随机例子来证明问题):

private static final int   MAN = 0x00000001;
private static final int WOMAN = 0x00000002;
// ...alive, hungry, blind, etc.
private static final int  DEAD = 0xFF000000;

public void doStuff(int human) {
    switch (human) {
    case MAN | DEAD:
        // do something
        break;
    // more common cases
    }
}
Run Code Online (Sandbox Code Playgroud)

如今,因为我们使用enumsEnumSets,我有时喜欢做类似的事情:

enum Human {
    MAN, WOMAN, DEAD; // etc.
}

public void doStuff(EnumSet human) {
    switch (human) {
    case Human.MAN | Human.DEAD:
        // do something …
Run Code Online (Sandbox Code Playgroud)

java enums switch-statement enumset bit-fields

7
推荐指数
2
解决办法
2410
查看次数

检查enumsets是否具有相同的枚举值

我有两个EnumSet.

EnumSet.of(A1, A2, A3);
EnumSet.of(A3, A4, A5, A6);
Run Code Online (Sandbox Code Playgroud)

我想找到两个集合中存在哪些值.(在这种情况下,A3.)

有没有快速的方法呢?

java collections enums enumset

7
推荐指数
4
解决办法
2154
查看次数

从String反序列化EnumSet的优雅方法

我想序列化一些EnumSet<FooType>,以String使用它的toString()方法.

例如:EnumSet.of(FooType.COMMON, FooType.MEDIUM).toString()会给[COMMON, MEDIUM].

问题是关于将这样的字符串反序列化为优雅的方法EnumSet<FooSet>.我正在寻找一些众所周知的库(可能是这样的apache-commons)或标准的Util-class来处理这类事情.

就像是: EnumSetUtil.valueOf(FooType.class, "[COMMON, MEDIUM]")

我用这样的方式实现了这个东西:

public static <E extends Enum<E>> EnumSet<E> valueOf(Class<E> eClass, String str) {
    String[] arr = str.substring(1, str.length() - 1).split(",");
    EnumSet<E> set = EnumSet.noneOf(eClass);
    for (String e : arr) set.add(E.valueOf(eClass, e.trim()));
    return set;
}
Run Code Online (Sandbox Code Playgroud)

但是,可能有现成的解决方案,或者这样做非常简单的方法.

java enums enumset

6
推荐指数
1
解决办法
3204
查看次数

如何在 kotlin 中初始化一个空的 EnumSet?

我对 Kotlin 还很陌生,并尝试创建一种位集枚举,其中整数对应于状态,并且我可以通过切换各个位来切换各个状态。但我坚持认为对象可以没有状态。

https://pl.kotl.in/L_fTBahVN

import java.util.*

fun main() {
    var d = Door(100, EnumSet.noneOf(Status))
}

enum class Status(intValue: Int) {
    OPEN(1),
    CLOSED(1 shl 1),
    CRACKED(1 shl 2),
    BROKEN(1 shl 3)
}

class Door(val id: Int, val status: EnumSet<Status>) {}
Run Code Online (Sandbox Code Playgroud)

此代码失败并出现错误Classifier 'Status' does not have a companion object, and thus must be initialized here

Status.class我正在读另一个问题,他们说在 内部使用EnumSet.noneOf,但这会引发更多错误。

enums enumset kotlin

6
推荐指数
1
解决办法
2056
查看次数

如何使用JPA2在实体中映射EnumSet(或枚举列表)

我有实体人:

@Entity
@Table(schema="", name="PERSON")
public class Person {
    List<PaymentType> paymentTypesList;
    //some other fields     
    //getters and setters and other logic
}
Run Code Online (Sandbox Code Playgroud)

我有枚举PaymentType:

public enum PaymentType {
    FIXED, CO_FINANCED, DETERMINED;
}
Run Code Online (Sandbox Code Playgroud)

如何持久化Person及其枚举列表(在此列表中我必须放置可变数量的枚举,可能有其中一个,或两个或全部)

我正在使用Spring和Postgres,实体是使用JPA注释创建的,并使用Hibernate进行管理.

mapping entity enumset

5
推荐指数
1
解决办法
2539
查看次数

Eclipse编译器和javac之间的差异 - 枚举,接口和泛型

以下代码在Eclipse中编译(并按预期运行测试):

import java.util.EnumSet;
public class EnumTest {

    static enum Cloneables implements Cloneable {
        One, Two, Three;
    }

    public <T extends Cloneable> T getOne(Class enumType) {
        EnumSet<? extends T> set = EnumSet.allOf(enumType);
        return set.iterator().next();
    }
}
Run Code Online (Sandbox Code Playgroud)

但是,javac直接或通过Maven 编译(JDK 7)失败,出现以下错误:

type argument ? extends T is not within bounds of type-variable E
Run Code Online (Sandbox Code Playgroud)

说实话,enums +接口+类型参数(泛型)的复杂性一下子就把我扔掉了,因为我正在编写代码,但我想我终于把它弄好了.

目标是编写这样的调用代码:

Cloneable something = enumTest.getOne(Cloneables.class);
Run Code Online (Sandbox Code Playgroud)

例如,在Eclipse中,以下测试编译并传递:

@Test
public void testGetFirst() {
    assertSame(Cloneables.One, getOne(Cloneables.class));
}
Run Code Online (Sandbox Code Playgroud)

任何有关"正确",Eclipse或javac的线索都值得赞赏.

同样值得赞赏的是关于实现该想法的替代方法的任何建议:将类作为可以使用的方法参数,EnumSet.allOf()并且还确定Enum对象的类型.EnumSet

顺便说一下,不要打扰批评这种方法的目的; 我已经从更有用/有意义的代码中减少了它.我对讨论"从枚举类型中找到第一个元素"的优点不感兴趣 - 这不是这个问题的重点.

java eclipse enums enumset

5
推荐指数
1
解决办法
248
查看次数

为什么 Java 21 的 EnumSet 不实现新的 SequencedSet 接口?

Java 21引入有序集合时,我非常高兴开始使用它们。但后来我很快发现JDK的各个角落似乎都会自然地应用新的排序接口,但它们并没有应用。我找不到对此的任何确认,也找不到任何证据表明未来有计划进一步将排序集合接口的使用扩展到更多 JDK 中。这让我感到惊讶,因为 JDK 的作者通常倾向于保持事物的一致性和完整性。

一个具体的例子是EnumSet。据我所知,没有根本原因EnumSet不能/不应该实施SequencedSet. 难道只是没有人愿意付出努力来实现一种reversed()方法吗EnumSet?或者有什么更严重的问题阻止了它?

java collections enumset java-21 sequencedset

5
推荐指数
2
解决办法
338
查看次数