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

发布于 2024-07-14 15:16:52 字数 1032 浏览 9 评论 0原文

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

例如:

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

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

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

影子的影子 2024-07-21 15:16:52

您的值应该是 2 的幂。

这样,当您对它们进行按位或运算时,您就不会丢失任何信息。

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;

等等

然后你可以这样做:

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

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.
}
天荒地未老 2024-07-21 15:16:52

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

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

使用 EnumSet 对于内存使用也很方便。

这是一个例子:

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

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");
    }
  }
}
甜点 2024-07-21 15:16:52

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

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

然后使用按位或来组合值,并使用按位与来测试设置值。

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

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
七分※倦醒 2024-07-21 15:16:52

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

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

那么你可以将 ONE 和 TWO 结合起来,例如:

ONE | TWO = 0000 0011

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

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

为了更好地理解其工作原理和原理,我建议您阅读一些有关二进制表示和逻辑的内容。 一个好地方是《汇编艺术》第 3 章

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.

叫嚣ゝ 2024-07-21 15:16:52

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

这里是维基百科中关于该主题的链接,它应该解释为什么你想要 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();
    }
}

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

Here is a link in wikipedia on the topic as well which should explain why you want powers of 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();
    }
}
鲸落 2024-07-21 15:16:52

当每一位都很重要时,使用位掩码很受欢迎。 今天实现此目的的另一种方法是使用更易于操作和扩展的枚举。

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

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.
        }
    }
}
一梦浮鱼 2024-07-21 15:16:52

首先,您不能以这种方式定义值来进行按位比较。 相反,设置不同的位:

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

其次,您可能应该使用 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}"

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}"
情痴 2024-07-21 15:16:52

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

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

非常简洁,但很有参考价值。

The Java Tutorial chapter on bitwise operations are at

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

It is very concise but good for reference.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文