How to use a bitwise operator to pass multiple Integer values into a function for Java?

16,570

Solution 1

Your values should be powers of 2.

That way, you don't lose any information when you bitwise-OR them.

public static final int ONE   = 0x01;
public static final int TWO   = 0x02;
public static final int THREE = 0x04;
public static final int FOUR  = 0x08;
public static final int FIVE  = 0x10;

etc.

Then you can do this:

public static void main(String [] args) {
    Example.multiValueExample(Values.ONE | Values.THREE | Values.FIVE);
}

public static void multiValueExample(int values){
    if ((values & Values.ONE) == Values.ONE) {
    }

    if ((values & Values.TWO) == Values.TWO) {
    }

    // etc.
}

Solution 2

As was already mentioned, consider use of enums instead of bit values.

According to Effective Java 2: "Item 32: Use EnumSet instead of bit fields"

Usage of EnumSet is quite effective for memory usage and very convenient.

Here is an example:

package enums;

import java.util.EnumSet;
import java.util.Set;

public class Example {
  public enum Values {
    ONE, TWO, THREE, FOUR, FIVE
  }

  public static void main(String[] args) {
    // should evaluate just Values.ONE
    Example.multiValueExample(EnumSet.of(Values.ONE));

    // should evalueate just values Values.ONE, Values.THREE, Values.FIVE
    Example.multiValueExample(EnumSet.of(Values.ONE, Values.THREE, Values.FIVE));

    // should evalueate just values Values.TWO , Values.FIVE
    Example.multiValueExample(EnumSet.of(Values.TWO, Values.FIVE));
  }

  public static void multiValueExample(Set<Values> values) {
    if (values.contains(Values.ONE)) {
      System.out.println("One");
    }

    // Other checks here...

    if (values.contains(Values.FIVE)) {
      System.out.println("Five");
    }
  }
}

Solution 3

You setup the integer values to be powers of two so that each enumerated value is a single bit in the binary representation.

int ONE = 0x1;    //0001
int TWO = 0x2;    //0010
int THREE = 0x4;  //0100
int FOUR = 0x8;   //1000

Then you use bit-wise OR to combine values and bitwise AND to test set values.

int test_value = (ONE | FOUR);   //-> 1001
bool has_one = (test_value & ONE) != 0;  //-> 1001 & 0001 -> 0001 -> true

Solution 4

The values you combine with | (binary OR, not logical OR [which is ||]) must not have overlapping "1"s in their bit representation. For example,

ONE = 0x1 =   0000 0001
TWO = 0x2 =   0000 0010
THREE = 0x3 = 0000 0011
FOUR = 0x4 =  0000 0100

Then you can combine ONE and TWO, for example:

ONE | TWO = 0000 0011

But you can't distinguish ONE | TWO from THREE, because there are overlapping bits. The numbers you combine should thus be powers of two, such that they don't overlap when OR'ed together. To test if a number was passed in "values", do:

if (values & ONE) {
    // ... then ONE was set
}

To better understand why and how this works, I recommend you read a bit on binary representation and logic. A good place is Chapter 3 of the Art of Assembly.

Solution 5

First, you can't define the Values that way to do bitwise comparisons. Instead, set different bits:

public static final int ONE   = 0x1;  // First bit is set
public static final int TWO   = 0x2;  // Second bit is set
public static final int THREE = 0x4;  // Third bit is set
public static final int FOUR  = 0x8;  // Fourth bit is set
public static final int FIVE  = 0x10; // Fifth bit is set

Second, you should probably be using java.util.BitSet for these sorts of operations:

BitSet bits = new BitSet(5);
bits.set(2);
bits.set(4);

System.out.println("these bits are set: " + bits);
// Prints "these bits are set: {2, 4}"

BitSet otherBits = new BitSet(5);
otherBits.set(3);
otherBits.set(4);

System.out.println("these bits are set: " + bits.or(otherBits));
// Prints "these bits are set: {2, 3, 4}"
Share:
16,570
AtariPete
Author by

AtariPete

Mobile Software Developer in the NYC area. Typically Blackberry, Android and iPhone development. I'm cofounder of Perk Mobile Inc. where we do mobile consulting and development. Also I organized the last MobileCampNYC3 event at Microsoft's NYC offices.

Updated on June 05, 2022

Comments

  • AtariPete
    AtariPete almost 2 years

    In application frameworks I keep seeing frameworks that allow you to pass in multiple Int values (generally used in place of an enum) into a function.

    For example:

    public class Example
    { 
        public class Values
        {
            public static final int ONE = 0x7f020000;
            public static final int TWO = 0x7f020001;
            public static final int THREE = 0x7f020002;
            public static final int FOUR = 0x7f020003;
            public static final int FIVE = 0x7f020004;
        }
    
        public static void main(String [] args)
        {
            // should evaluate just Values.ONE
            Example.multiValueExample(Values.ONE);
    
            // should evalueate just values Values.ONE,  Values.THREE, Values.FIVE
            Example.multiValueExample(Values.ONE | Values.THREE | Values.FIVE);
    
            // should evalueate just values Values.TWO , Values.FIVE
            Example.multiValueExample(Values.TWO | Values.FIVE);
        }
    
        public static void multiValueExample(int values){
            // Logic that properly evaluates bitwise values
            ...
        }
    }
    

    So what logic should exist in multiValueExample for me to properly evaluate multiple int values being passed in using the bitwise operator?