将带有属性的枚举转换为 Java 中的映射

huangapple go评论59阅读模式
英文:

Convert Enum with attributes to map in Java

问题

我有一个如下的枚举:

@AllArgsConstructor
public enum EnumExample {
    VAL1("val1 description", 100),
    VAL2("val2 description", 200);

    String description;
    int value;
}

现在我想要将所有带有属性的枚举值返回为以下形式的映射列表:

[
  {
    "name": "VAL1",
    "description": "val1 description",
    "value": 100
  },
  {
    "name": "VAL2",
    "description": "val2 description",
    "value": 200
  }
]

我可以使用以下代码来实现:

Arrays.stream(EnumExample.values())
      .map(enumExample -> 
              ImmutableMap.of("name", enumExample.name(),
                              "description", enumExample.description,
                              "value", enumExample.value))
      .collect(Collectors.toList())

但我想知道是否有更好的方法在不显式转换 EnumExample 为 Map 的情况下实现相同的效果。如果添加了新的属性,那么新的 K, V 对应关系应该出现在结果映射中。

我尝试过以下方法,但都只返回枚举值 [VAL1, VAL2]

  • com.google.common.collect.Lists.newArrayList(EnumExample.values())
  • Arrays.stream(EnumExample.values()).collect(Collectors.toList())

我还尝试了转换为映射,但返回的结果为 {VAL2=VAL2, VAL1=VAL1}

Arrays.stream(EnumExample.values())
      .collect(Collectors.toMap(o -> o, Function.identity()))

如果有任何指引或更好的方法,无需手动创建映射,即可在不需要手动创建每个枚举的映射的情况下返回带有属性的枚举值,我将不胜感激。

我的要求是:

在一个 Web 服务中,将所有枚举值及其属性一起返回给客户端。客户端有解析所有属性的逻辑。比如,今天有一个名为 _description_ 的属性,明天如果有新的属性,比如 boolean manadatoryField,那么客户端只需要处理它。但是从服务器端来看,我无法在不手动创建每个枚举的映射的情况下返回带有属性的枚举值。

英文:

I have an enum as below:

@AllArgsConstructor
public enum EnumExample {
    VAL1("val1 description", 100),
    VAL2("val2 description", 200);

    String description;
    int value;
}

Now I want to return all enum values with attributes as a list of the map as below:

[
  {
    "name": "VAL1",
    "description": "val1 description",
    "value": 100
  },
  {
    "name": "VAL2",
    "description": "val2 description",
    "value": 200
  }
]

I am able to achieve this using the below code:

Arrays.stream(EnumExample.values())
      .map(enumExample -> 
              ImmutableMap.of("name", enumExample.name(),
                              "description", enumExample.description,
                              "value", enumExample.value))
      .collect(Collectors.toList())

But I want to know if there any best way to achieve the same without explicitly converting EnumExample to Map. If any new attribute gets added then it should be coming in the resulting map as a new K, V pair.

I tried the below ways but both return only enum values [VAL1, VAL2].

  • com.google.common.collect.Lists.newArrayList(EnumExample.values())
  • Arrays.stream(EnumExample.values()).collect(Collectors.toList())

Tried to convert to map too but returns {"VAL2":"VAL2","VAL1":"VAL1"}.

Arrays.stream(EnumExample.values())
      .collect(Collectors.toMap(o -> o, Function.identity()))

Any leads or better ways that doesn't require a manual map creation is appreciated.

My requirement:

In a webservice, return all the Enum values along with attributes to the client. The client has the logic to parse all the attributes coming. Like today there is a description attribute and tomorrow if new attribute like boolean manadatoryField, then it only needs to be handled by client. But from the server end, I am unable to return the Enum values with attributes without manually creating a map out of each enum and returning the map.

答案1

得分: 1

发现了使用 Jackson 进行的另一种简单方法:

为枚举添加注解。

@Getter
@JsonFormat(shape = JsonFormat.Shape.OBJECT)

name 添加显式的 getter 方法。

public String getName() {
    return this.name();
}

new ObjectMapper().writeValueAsString(EnumExample.values()) 返回一个有效的 JSON,可以转换为 Map。在我的情况下,我将其返回给客户端!

英文:

Found a simple and another way of doing using Jackson:

Add annotations to the enum.

@Getter
@JsonFormat(shape = JsonFormat.Shape.OBJECT)

Add an explicit getter for name

public String getName() {
    return this.name();
}

new ObjectMapper().writeValueAsString(EnumExample.values()) returns a valid JSON which can be converted to Map. In my case I return, this to client!

答案2

得分: 0

回答自己的问题以帮助他人。如果这是唯一的方法,那么请点赞。

Arrays.stream(EnumExample.values())
      .map(enumExample -> 
              ImmutableMap.of("name", enumExample.name(),
                              "description", enumExample.description,
                              "value", enumExample.value))
      .collect(Collectors.toList())

非常欢迎任何无需显式转换EnumExample为Map就能实现相同效果的最佳方法。例如,如果添加了任何新属性,则应作为新的K,V对出现在结果映射中。

英文:

Answering my own question to help others. If this is the only way, then do upvote.

Arrays.stream(EnumExample.values())
      .map(enumExample -> 
              ImmutableMap.of("name", enumExample.name(),
                              "description", enumExample.description,
                              "value", enumExample.value))
      .collect(Collectors.toList())

Any best way to achieve the same without explicitly converting EnumExample to Map is greatly appreciated. For example, If any new attribute gets added then it should be coming in the resulting map as a new K, V pair.

huangapple
  • 本文由 发表于 2020年9月15日 00:05:27
  • 转载请务必保留本文链接:https://go.coder-hub.com/63887980.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定