【问题标题】:use Lombok @Builder @Default @Singular to initialise List<>使用 Lombok @Builder @Default @Singular 初始化 List<>
【发布时间】:2019-05-04 19:50:23
【问题描述】:

免责声明:我对 Java 有点陌生 :)

我正在对一些数据进行一系列选择,为了跟踪选择的每个阶段发生的情况,我使用int 计数器。这些计数器都在一个数据对象中:

public class MyCounters {
    private int counter0;
    private int counter1;
    ...
}

我还必须计算有多少候选人最终属于给定数量的类别,我用enum 来说明这一点。为此,我创建了List&lt;Integer&gt;,其中列表的索引覆盖了枚举的值。

private List<Integer> myList;

稍后在代码中我需要一个专用方法来用零初始化列表:

for (MyEnum i : MyEnum.values()) {
    myList.add(0);
}

然后,在主代码中,一旦分配了最终类别,就会发生这种情况:

myCounters.getMyList().set(myEnum.ordinal(), myCounters.getList().get(myEnum.ordinal()) + 1);

有人建议我可以使用 Lombok 的 @Builder.Default 功能(或者可能是 @Singular)改进声明/初始化步骤,但我真的不知道如何:最后我需要初始化一个 List&lt;Integer&gt;与enum 中的值一样多的零。 真的可以使用 Lombok 的扩展来做到这一点吗?还是他们针对不同的东西?

【问题讨论】:

  • 我不知道是谁给了你这个建议,但这听起来像 bad 建议。我看不出这有什么关系。你最好让告诉你的人给你一个例子,因为它似乎对你没有帮助。

标签: java lombok


【解决方案1】:

坚持您的架构,我猜您必须在使用 Lombok 的类中初始化 List。可以通过以下方式实现:

@Builder
public class Foo {

  @Builder.Default
  private List<Integer> myList = Arrays.asList(0, 0, 0);

}

Arrays.asList 是使用标准 Java 库使用默认值初始化 List 的方法。我知道使用名为 Arrays 的类而不是 List 或 Collection 可能会有些混乱,但您可以找到有关其 Javadoc 的更多信息(here Java 8 的文档)。该初始化的结果是一个列表,其中三个整数设置为 0。您只需放置所需的数量即可。

在myList 字段上使用注释@Builder.Default 的原因是让构建器构造器知道默认初始化,否则Lombok 的构建器会跳过该初始化。

为简洁起见,我只包含了用于初始化您的列表和构建器的非常具体的代码。请注意,您可能还想结合使用 Lombok 注释 @Data 和 @AllArgsConstructor。

您可以在the Lombok official documentation找到更多信息

【讨论】:

  • 非常感谢@Niccolò 这非常有用,我想这确实是我想要做的(没有成功)!!我看到元素的数量是硬编码的,而不是根据枚举中的元素设置的,所以我会尝试一下我收到的其他一些建议。是的,我已经在使用@Data 和其他注释:)
【解决方案2】:

老实说,我建议使用不同的架构:

  • 考虑不使用Enum.ordinal()。如果您只关心“一个”时间点,它会正常工作,但如果您以某种方式持久化数据,那么一旦您想要比较不同的持久化数据(同时枚举发生变化),事情就会崩溃
  • 可以考虑LongAdder。

含义:使用Map&lt;YourEnumType, LongAdder&gt; 来计算事物。检索计数器,调用它的add() 方法,完成。

【讨论】:

  • 非常感谢您的评论!我开始了解 Java,每条信息都很有用!尽管如此,我还是决定按照@TomaszLinkowski 的建议使用EnumMap
【解决方案3】:

Lombok 的@Builder + @Singular 会自行使用空的ArrayList 初始化您的List,仅此而已(他们不会使用任何元素(例如零)初始化此List)。 @Builder.Default 可以做到这一点(那时你不需要@Singular),但如果可能的话我不会走这条路。

我不完全了解您想要做什么,例如不知道你是只有一个enum(MyEnum),还是有不止一个enum。

如果你只有MyEnum,你会更好使用与List不同的数据结构:

  1. EnumMap 是一个简单的选择,因为它是 Java 原生的:

    • 初始化:EnumMap&lt;MyEnum, Integer&gt; myMap = new EnumMap&lt;&gt;(MyEnum.class)
    • 递增:myMap.merge(myEnum, 1, Integer::sum)
    • 最终结果:myMap.getOrDefault(myEnum, 0)
  2. 不过,最好的数据结构是multiset。一个支持多组的外部库是Guava 及其Multiset:

    • 初始化:Multiset&lt;MyEnum&gt; myMultiset= HashMultiset.create()
    • 递增:myMultiset.add(myEnum)
    • 最终结果:myMultiset.count(myEnum)

【讨论】:

  • 非常感谢!这不是我想要的,但绝对比我想象的要好!!我使用了EnumMap,它工作正常(并解决了我试图解决的另一个小问题)
猜你喜欢
  • 2015-12-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多