如何使用按位运算符将多个整数值传递给 Java 函数?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/648021/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 13:12:27  来源:igfitidea点击:

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

javafunctionbit-manipulationbitwise-operatorsinteger

提问by AtariPete

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.

在应用程序框架中,我一直看到允许您将多个 Int 值(通常用于代替枚举)传递到函数中的框架。

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?

那么 multiValueExample 中应该存在什么逻辑来正确评估使用按位运算符传入的多个 int 值?

回答by Can Berk Güder

Your values should be powers of 2.

您的值应该是 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.
}

回答by Andrey Vityuk

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

正如已经提到的,考虑使用枚举而不是位值。

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

根据Effective Java 2“第 32 项:使用EnumSet而不是位字段”

Usage of EnumSetis quite effective for memory usage and very convenient.

的使用EnumSet是内存使用,非常方便非常有效。

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");
    }
  }
}

回答by user21714

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

您将整数值设置为 2 的幂,以便每个枚举值都是二进制表示中的一个位。

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.

然后您使用按位 OR 组合值并使用按位 AND 来测试设置值。

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

回答by Joao da Silva

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

您结合的值 | (二进制 OR,不是逻辑 OR [这是 ||])在它们的位表示中不能有重叠的“1”。例如,

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,例如:

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:

但你无法区分ONE | 两个从三个,因为有重叠的位。因此,您组合的数字应该是 2 的幂,这样它们在进行 OR 运算时就不会重叠。要测试是否在“值”中传递了数字,请执行以下操作:

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.

为了更好地理解为什么以及如何工作,我建议您阅读一些关于二进制表示和逻辑的内容。一个好地方是组装艺术的第 3 章

回答by John Feminella

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.BitSetfor these sorts of operations:

其次,您可能应该将java.util.BitSet用于这些类型的操作:

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}"

回答by TofuBeer

Well if they are powers of 2 you would do something like the "display" method in the code below.

好吧,如果它们是 2 的幂,您将在下面的代码中执行类似于“显示”方法的操作。

Here is a link in wikipediaon the topic as well which should explain why you want powers of 2.

这是维基百科中关于该主题的链接,它应该解释为什么你想要 2 的幂。

public class Main
{
    private static final int A = 0x01;
    private static final int B = 0x02;
    private static final int C = 0x04;

    public static void main(final String[] argv)
    {
        display(A);
        display(B);
        display(C);
        display(A | A);
        display(A | B);
        display(A | C);
        display(B | A);
        display(B | B);
        display(B | C);
        display(C | A);
        display(C | B);
        display(C | C);
        display(A | A | A);
        display(A | A | B);
        display(A | A | C);
        display(A | B | A);
        display(A | B | B);
        display(A | B | C);
        display(A | C | A);
        display(A | C | B);
        display(A | C | C);
        display(B | A | A);
        display(B | A | B);
        display(B | A | C);
        display(B | B | A);
        display(B | B | B);
        display(B | B | C);
        display(B | C | A);
        display(B | C | B);
        display(B | C | C);
        display(C | A | A);
        display(C | A | B);
        display(C | A | C);
        display(C | B | A);
        display(C | B | B);
        display(C | B | C);
        display(C | C | A);
        display(C | C | B);
        display(C | C | C);
    }

    private static void display(final int val)
    {
        if((val & A) != 0)
        {
            System.out.print("A");
        }

        if((val & B) != 0)
        {
            System.out.print("B");
        }

        if((val & C) != 0)
        {
            System.out.print("C");
        }

        System.out.println();
    }
}

回答by Peter Lawrey

Using bit masks were popular when every bit counted. Another way to do this today is to use enums with are simpler to manipulate and extend.

当每一位都计算在内时,使用位掩码很流行。今天的另一种方法是使用枚举更易于操作和扩展。

import static Example.Values.*;
import java.util.Arrays;

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

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

        // should evaluate just values Values.ONE,  Values.THREE, Values.FIVE
        multiValueExample(ONE, THREE, FIVE);

        // should evaluate just values Values.TWO , Values.FIVE
        multiValueExample(TWO, FIVE);
    }

    public static void multiValueExample(Values... values){
        // Logic that properly evaluates
        System.out.println(Arrays.asList(values));
        for (Values value : values) {
            // do something.
        }
    }
}

回答by Thorbj?rn Ravn Andersen

The Java Tutorial chapter on bitwise operations are at

关于按位运算的 Java 教程章节位于

http://java.sun.com/docs/books/tutorial/java/nutsandbolts/op3.html

http://java.sun.com/docs/books/tutorial/java/nutsandbolts/op3.html

It is very concise but good for reference.

它非常简洁,但可供参考。