How to merge two unmodifiable Sets in Java?

3.2k Views Asked by At

How to merge two unmodifiable static final sets?

public static final Set<Long> ORG_SUBSCRIBER_ALLOWED_NUMBER_CD = Set.of(COMPANY_GST, GOVERNMENT_BODY_GST);

public static final Set<Long> INDIVIDUAL_SUBSCRIBER_ALLOWED_NUMBER_CD = Set.of(BUSINESS_PAN, INDIVIDUAL_PAN);

I want to combine the above static final sets into one set (one-statement initialization), because it's a Class variable

public static final Set<Long> SUBSCRIBER_ALLOWED_NUMBER_CD = ?
5

There are 5 best solutions below

1
ernest_k On BEST ANSWER

A one-statement initialization, if preferred:

public static final Set<Long> SUBSCRIBER_ALLOWED_NUMBER_CD = 
     Collections.unmodifiableSet(
        Stream.of(ORG_SUBSCRIBER_ALLOWED_NUMBER_CD, 
                  INDIVIDUAL_SUBSCRIBER_ALLOWED_NUMBER_CD)
              .flatMap(Set::stream)
              .collect(Collectors.toSet()));

Or, perhaps more readable:

public static final Set<Long> SUBSCRIBER_ALLOWED_NUMBER_CD;
static {
    Set<Long> all = new HashSet<>();
    all.addAll(ORG_SUBSCRIBER_ALLOWED_NUMBER_CD);
    all.addAll(INDIVIDUAL_SUBSCRIBER_ALLOWED_NUMBER_CD);
    
    SUBSCRIBER_ALLOWED_NUMBER_CD = Collections.unmodifiableSet(all);
}

Ignore the Collections.unmodifiableSet call if the third set is not expected to be unmodifiable.

2
Tim Biegeleisen On

Any reason why you can't create a third set and just add both of the two final sets?

Set<Long> SUBSCRIBER_ALLOWED_NUMBER_CD = new HashSet<>();
SUBSCRIBER_ALLOWED_NUMBER_CD.addAll(ORG_SUBSCRIBER_ALLOWED_NUMBER_CD);
SUBSCRIBER_ALLOWED_NUMBER_CD.addAll(INDIVIDUAL_SUBSCRIBER_ALLOWED_NUMBER_CD);

The first two sets' being final just means that you can't modify those sets. It does not prevent you from reading the sets into another new collection.

3
Youcef LAIDANI On

If you want to use streams:

public static final Set<Long> SUBSCRIBER_ALLOWED_NUMBER_CD =
    Stream.of(ORG_SUBSCRIBER_ALLOWED_NUMBER_CD, INDIVIDUAL_SUBSCRIBER_ALLOWED_NUMBER_CD)
        .flatMap(Set::stream)
        .collect(Collectors.toSet());

Or, in your case, and as mentioned in comment, you can use Collectors.toUnmodifiableSet() :

public static final Set<Long> SUBSCRIBER_ALLOWED_NUMBER_CD =
    Stream.of(ORG_SUBSCRIBER_ALLOWED_NUMBER_CD, INDIVIDUAL_SUBSCRIBER_ALLOWED_NUMBER_CD)
        .flatMap(Set::stream)
        .collect(Collectors.toUnmodifiableSet());
1
Hadi On

Stream#concat is useful too

Set<Long> SUBSCRIBER_ALLOWED_NUMBER_CD  =  
         Stream.concat(ORG_SUBSCRIBER_ALLOWED_NUMBER_CD.stream(),
                       INDIVIDUAL_SUBSCRIBER_ALLOWED_NUMBER_CD.stream())
                .collect(Collectors.toSet());
0
drekbour On

Just to point out that Guava still handles this case more more readably (and probably much more performant) than the JDK-only solutions:

public static final Set<Long> SUBSCRIBER_ALLOWED_NUMBER_CD = ImmutableSet.builder()
    .addAll(ORG_SUBSCRIBER_ALLOWED_NUMBER_CD)
    .addAll(INDIVIDUAL_SUBSCRIBER_ALLOWED_NUMBER_CD)
    .build();