Skip to content

Select enum constants from boolean[] or bit mask#44

Open
runeflobakk wants to merge 5 commits intomainfrom
select-enums-from-bits-n-bools
Open

Select enum constants from boolean[] or bit mask#44
runeflobakk wants to merge 5 commits intomainfrom
select-enums-from-bits-n-bools

Conversation

@runeflobakk
Copy link
Member

Use a bit mask to select constants from an enum, based on which indices which are set (1-bits):

<E extends Enum<E>> Stream<E> DiggEnums.selectByBitmask(BitSet, Class<E>)

Use an array of booleans to select constants from an enum, based on which indices which are true;

<E extends Enum<E>> Stream<E> DiggEnums.selectByIndexAsOrdinals(boolean[], Class<E>)

Use case

This is obviously a bit esoteric functionality. The intention is to ease the use of some APIs which may (probably for valid performance reasons, at least at the time the APIs were defined) return a kind of bitmask to represent a standardized set of possibly set or unset values.

An example of this is X509Certificate.getKeyUsage(), which returns an array of booleans, where each element's position in the array indicate if a known set of ordered values is true or false. This will enable e.g. the following:

/// Enum representation of the X.509 KeyUsage extension (OID = 2.5.29.15).
/// The order of constants reflect the order of the ASN.1 definition, see
/// [X509Certificate#getKeyUsage()].
enum KeyUsage {
    digitalSignature,
    nonRepudiation,
    keyEncipherment,
    dataEncipherment,
    keyAgreement,
    keyCertSign,
    cRLSign,
    encipherOnly,
    decipherOnly;

    static Stream<KeyUsage> allFrom(X509Certificate certificate) {
        return selectByIndexAsOrdinals(certificate.getKeyUsage(), KeyUsage.class);
    }
}

Note on EnumSet

Java already has a way to represent a set of enum constants using a compact and efficient bitmask, but no way to construct the EnumSet using a bitmask as the source.

@runeflobakk runeflobakk requested a review from haralkvi March 6, 2026 14:18
@runeflobakk runeflobakk force-pushed the select-enums-from-bits-n-bools branch 2 times, most recently from ddcd566 to 0a7477e Compare March 6, 2026 14:27
if (candidates.length == 0) {
return Stream.empty();
}
return mask.get(0, candidates.length).stream().mapToObj(selectedOrdinal -> candidates[selectedOrdinal]);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Jeg skjønner åpenbart ikke hvordan dette virker… vil ikke selectedOrdnial alltid bare være 0 eller 1?

Copy link
Member Author

@runeflobakk runeflobakk Mar 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ja, den er sneaky 😅
Et BitSet er ikke en Collection (eller java.util.Set), det er en helt standalone struktur for å behandle bit-sekvenser.

BitSet.stream() gir ikke hvert av elementene i bit-sekvensen, altså en strøm med 0-er og 1-ere og som typisk ville vært ekvivalent til å kalle .stream() på en collection, men (hold deg fast) indeksene til de bit-ene som er satt, altså hvilke bits som er 1. Dette gir altså en strøm-linjeformet (høhø) tilgang til hvilke bits som er "påskrudd", fremfor å selv traversere alle bits, holde styr på hvilke posisjon man er på og sjekke 0 vs. 1 etc.

Edit: Det som kanskje ikke er åpenbart her heller, er at BitSet.get(0, candidates.length) gir et nytt BitSet, og ikke en collection hvor man får det antallet første bits man spesifiserer, også kaller .stream() på en sånn collection.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BitSet.stream() gir ikke hvert av elementene i bit-sekvensen, altså en strøm med 0-er og 1-ere […], men […] indeksene til de bit-ene som er satt, altså hvilke bits som er 1.

Da gir det straks mer mening! 💡

Only log warns, and use System.out (not slf4j-simple's default
System.err)
Grouping into nested test classes
@runeflobakk runeflobakk force-pushed the select-enums-from-bits-n-bools branch from 0a7477e to 5d337c0 Compare March 6, 2026 15:16
A BitSet constructed from a long is interpreted little endian, i.e. the
bits of a long is traversed "from right-to-left".
@runeflobakk runeflobakk force-pushed the select-enums-from-bits-n-bools branch from ef33d0e to cd52ab5 Compare March 6, 2026 15:50
Copy link

@haralkvi haralkvi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants