record-builder icon indicating copy to clipboard operation
record-builder copied to clipboard

[BUG]Order in collection is not preserved while using useImmutableCollections option

Open pawellabaj opened this issue 2 years ago • 8 comments

When a record has a component of the type that is the Set implementation keeping the order, the order is lost when using useImmutableCollections = true option.

Following test shows the problem:

import io.soabase.recordbuilder.core.RecordBuilder;

import java.util.Set;

@RecordBuilder
@RecordBuilder.Options(useImmutableCollections = true)
record OrderedSetRecord(Set<String> orderedSet) {}
import org.junit.jupiter.api.Test;

import java.util.LinkedHashSet;

import static org.assertj.core.api.Assertions.assertThat;

public class TestOrderedSetsBuilder {

    @Test
    void shouldKeepOrderInSetIfProvided() {
        // given
        var orderedSet = new LinkedHashSet<String>();
        orderedSet.add("C");
        orderedSet.add("B");
        orderedSet.add("A");

        // when
        var record = OrderedSetRecordBuilder.builder().orderedSet(orderedSet).build();

        // then
        assertThat(record.orderedSet()).containsExactly("C", "B", "A");
    }
}

Order is lost in java.util.Set#copyOf method used in generated __set method.

One of possible solution is te generate __set method as follow:

private static <T> Set<T> __set(Collection<? extends T> o) {
        return (o != null) ?  Collections.unmodifiableSet((Set<T>) o) : Set.of();
    }

pawellabaj avatar Jun 08 '23 15:06 pawellabaj

unmodifiableSet unfortunately only creates a view on the still modifiable original set. Meaning that from a reference to the underlying set the new "unmodifiable" set could change. This is ofc not desirable.

freelon avatar Jun 13 '23 20:06 freelon

In most cases, reference to the original collection is not being kept and collection from the record is used.

Another possible solution would be to treat java.util.LinkedHashSet or com.google.common.collect.ImmutableSet in a special way.

pawellabaj avatar Jun 17 '23 20:06 pawellabaj

Introducing the useUnmodifiableCollections option works for me. However, it didn't solve the issue reported here. Possibly checking for specialized interfaces like SortedSet, etc. (see #151 ) is the solution.

pawellabaj avatar Jul 04 '23 19:07 pawellabaj

@pawellabaj could you provide a PR?

Randgalt avatar Jul 05 '23 06:07 Randgalt

@Randgalt , I'm thinking of it.

Do you consider introducing Guava as a dependency to your project?

pawellabaj avatar Jul 05 '23 07:07 pawellabaj

Do you consider introducing Guava as a dependency to your project

No - we shouldn't do that. We could, however, do FQPN string comparisons if needed.

Randgalt avatar Jul 05 '23 07:07 Randgalt

@Randgalt have you thought about introducing a plugins/extensions mechanism? Extensions with the usage of any library could be implemented.

pawellabaj avatar Aug 05 '23 11:08 pawellabaj

At this point I'd like to limit any new customizations. This library ran into a lot of problems with some of the recently added customizations.

Randgalt avatar Sep 20 '23 06:09 Randgalt