use Lombok @Builder @Default @Singular to initialise List<>

FrancescoLS :

Disclaimer: I am kind of new to Java :)

I am running a bunch of selections on some data and in order to keep track of what happens at each stage of the the selection I use int counters. These counters are all in a data object:

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

I also have to count how many candidates end up in a given number of categories, which I account for with an enum. To do this I created List<Integer> where the index of the list covers the values of the enum.

private List<Integer> myList;

And later in the code I need a dedicated method to initialise the list with zeros:

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

In the main code then, once the final category has been assigned, this happens:

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

I was suggested that the declaration/initialisation steps can be improved using Lombok's @Builder.Default functionality (or maybe @Singular), but I can't really find out how: in the end I need to initialise a List<Integer> to as many zeros as the values in the enum. Is it really possible to do this using Lombok's extensions? Or are they targeted for something different?

Tomasz Linkowski :

Lombok's @Builder + @Singular on their own will initialize your List with an empty ArrayList, and that's it (they won't initialize this List with any elements, like zeroes). @Builder.Default could do that (you don't need @Singular then), but I would not follow that path if possible.

I don't fully understand what you want to do, e.g. I don't know if you have only one enum (MyEnum), or if there's more than one enum.

If you have only MyEnum, you'd be much better off using a different data structure than List:

  1. An EnumMap is the easy choice, because it's native to Java:

    • initialization: EnumMap<MyEnum, Integer> myMap = new EnumMap<>(MyEnum.class)
    • incrementing: myMap.merge(myEnum, 1, Integer::sum)
    • final result: myMap.getOrDefault(myEnum, 0)
  2. The best data structure for this, though, would be a multiset. One external library that supports mulitsets is Guava with its Multiset:

    • initialization: Multiset<MyEnum> myMultiset= HashMultiset.create()
    • incrementing: myMultiset.add(myEnum)
    • final result: myMultiset.count(myEnum)

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=102789&siteId=1