!!!!! There is now a project with much better code than this !!!!! http://claude-martin.ch/enumbitset/ I made this because enums can not easily be stored to bit fields. Set and bitwise operations are equally difficult. I put this on pastebin because it's just one single interface. I will edit this paste if I change anything. Maybe I'll put in on a repository later. Note that I didn't really test this! You can use it for whatever you want. There is no copyright. But it would be nice if you would keep my name in the file. ----------------- package ch.claude_martin.java8; import java.math.BigInteger; import java.util.Arrays; import java.util.BitSet; import java.util.EnumSet; import java.util.Set; /** * This adds support to use bit fields and bit masks for the enym type. The set * of enum values is interpreted as a bit set, which can be stored to a bit * field. * *
* Since this is an interface it does not change the state of the element it is * used on or any parameters. Instead it always returns a newly created object. * I.e. all methods that take a Set return a new Set. If you wish to alter the * set you can simply use the methods of that set. * *
* Bit fields are by default of type {@link BigInteger}, but {@link BitSet} and * {@link Long long} can be used as well. Bit masks should not be stored into a * database unless you can guarantee that no changes are made in the future. The * only change that would not break your code is to add new enums at the end of * the list of existing enums. Note that {@link EnumSet} and {@link BigInteger} * already has many methods to help using sets of enums and large integers. * *
* A bit field is always used to store a set of bits. Each bit can represent one * enum value. each enum has a distinct {@link #bitmask() bit mask}. * *
* Java 8 Beta has still a bug that does not allow assert statements in * interfaces: https:/ * /bugs.openjdk.java.net/browse/JDK-8025141 * *
* Nomenclature: *
Planet.class** public enum Planet { * MERCURY, VENUS, EARTH, ... * } *
* The goal of this interface is to use only existing types. Since all primitive
* types are limited this uses {@link BigInteger} instead.
*
* @author Claude Martin
*
* @param
* This is equivalent to:
* This is equivalent to: true, if this can be found.
*/
public default boolean elementOf(final Enum>... set) {
for (final Enum> e : set)
if (e == this)
return true;
return false;
}
/**
* Returns whether this enum can be found in the set of enums of the same
* type.
*
* set.contains(this);
*
*
* @returns true, if this can be found.
*/
public default boolean elementOf(final Setthis added.
*
* @returns A new {@link EnumSet} including all given elements and also
* this.
*/
@SuppressWarnings("unchecked")
public default EnumSetthis added.
*
* @returns A new {@link EnumSet} including all elements of the set and also
* this.
*/
@SuppressWarnings("unchecked")
public default EnumSetthis removed.
*
* @returns A new {@link EnumSet} with all given enums, except
* this. A copy of the set is returned if
* this is not present.
*/
@SuppressWarnings("unchecked")
public default EnumSetthis removed.
*
* @returns A new {@link EnumSet} with all elements of the set, except
* this. A copy of the set is returned if
* this is not present.
*/
public default EnumSetthis.
*
* EnumSet.complementOf(this.asSet())
*
* @returns A new {@link EnumSet} with all elements except this.
*/
@SuppressWarnings("unchecked")
public default EnumSetthis.
*
* @returns A new {@link EnumSet} containing this.
*/
@SuppressWarnings("unchecked")
public default EnumSetthis.
*
* @returns A new {@link EnumSet} containing this.
*/
@SuppressWarnings("unchecked")
public default BitSet asBitSet() {
final E e = (E) this;
final BitSet result = new BitSet();
result.set(e.ordinal());
return result;
}
/**
* Bitmask for this. The value is based on the ordinal.
*
* @return 1<<this.ordinal()
* @deprecated This is actually the same as {@link #bitmask()}. This is here
* so that programmers will find and use {@link #bitmask()}.
*/
@Deprecated
public default BigInteger asBigInteger() {
return this.bitmask();
}
/**
* 64 bit bitmask for this. The value is based on the ordinal.
*
* @return 1<<this.ordinal()
*/
@SuppressWarnings("unchecked")
public default long bitmask64() {
final E e = (E) this;
// assert EnumSet.allOf(e.getClass()).size() <= 64;
return 1 << e.ordinal();
}
/**
* Bitmask for this. The value is based on the ordinal.
*
* @return 1<<this.ordinal()
*/
@SuppressWarnings("unchecked")
public default BigInteger bitmask() {
final E e = (E) this;
return BigInteger.ONE.shiftLeft(e.ordinal());
}
/**
* Returns whether this value is set in the given bitmask.
*
* @param bitmask64
* A bitmask.
* @return (this.bitmask64() & bitmask8) != 0;
*/
public default boolean elementOf(final long bitmask64) {
return (this.bitmask64() & bitmask64) != 0;
}
/**
* Returns whether this value is set in the given bitmask.
*
* @param bitmask
* A bitmask.
* @return (this.bitmask() & bitmask) != 0
*/
public default boolean elementOf(final BigInteger bitmask) {
return !this.bitmask().and(bitmask).equals(BigInteger.ZERO);
}
/**
* Returns whether this value is set in the given bitset.
*
* @param bitset
* @return bitset.get(this.ordinal());
*/
@SuppressWarnings("unchecked")
public default boolean elementOf(final BitSet bitset) {
return bitset.get(((E) this).ordinal());
}
/** Creates a 64 bit bitmask of a given set of enums. */
public static this and all arguments, then applies
* logical OR to all. This results in a bitmask for all given enums (including
* this).
*
* @see #or(Enum...)
* @see EnumSet#of(Enum)
* @return this.bitmask64() | arg0.bitmask64() | ... | argN.bitmask64()
*/
@SuppressWarnings("unchecked")
public default
* Planet.EARTH.or(Planet.MARS, Planet.JUPITER)
*
* Planet.of(Planet.EARTH, Planet.MARS, Planet.JUPITER)
* However, this method returns a bitmask of type BigInteger.
*
* @see EnumSet#of(Enum)
* @see #or(BigInteger)
* @return this.bitmask() | arg0.bitmask() | ... | argN.bitmask()
*/
@SuppressWarnings("unchecked")
public default this and mask, then applies
* logical OR. This results in a new bitmask that also includes
* this.
*
* @see #addedTo(BigInteger)
* @see #addedTo(EnumSet)
* @see #addedTo(Enum...)
* @return mask.or(this.bitmask())
*/
public default mask.and(this.bitmask())
*/
public default mask.xor(this.bitmask())
*/
public default mask.andNot(this.bitmask())
*/
public default