在switch中使用数组作为case语句

Tod*_*dev 76 java arrays switch-statement

我试图做这样的事情,即在switch语句中使用数组.在Java中有可能吗?如果不是,请解释可能的解决方案.

boolean[] values = new boolean[4];

values[0] = true;
values[1] = false;
values[2] = false;
values[3] = true;

switch (values) {
    case [true, false, true, false]:
        break;
    case [false, false, true, false]:
        break;
    default:
        break;
}
Run Code Online (Sandbox Code Playgroud)

Mar*_*aux 73

@sᴜʀᴇsʜᴀᴛᴛᴀ是对的.但我想补充一些东西.从Java 7开始,switch语句支持Strings,所以你可以用它做点什么.它真的很脏,我不推荐,但这有效:

boolean[] values = new boolean[4];

values[0] = true;
values[1] = false;
values[2] = false;
values[3] = true;

switch (Arrays.toString(values)) {
    case "[true, false, true, false]":
        break;
    case "[false, false, true, false]":
        break;
    default:
        break;
}
Run Code Online (Sandbox Code Playgroud)

对于那些关心表现的人:你是对的,这不是超级快.这将编译成这样的东西:

String temp = Arrays.toString(values)
int hash = temp.hashCode();
switch (hash)
{
    case 0x23fe8da: // Assume this is the hashCode for that
                    // original string, computed at compile-time
        if (temp.equals("[true, false, true, false]"))
        {

        }
        break;
    case 0x281ddaa:
        if (temp.equals("[false, false, true, false]"))
        {

        }
        break;

    default: break;
}
Run Code Online (Sandbox Code Playgroud)

  • 同时创意和可怕.+1 (72认同)
  • 太限制了数组的大小,如果数组的大小发生变化,那么维护它是多么的混乱. (3认同)

Sur*_*tta 64

,只是你不能.

SwitchStatement:
    switch ( Expression ) SwitchBlock
Run Code Online (Sandbox Code Playgroud)

Expression的类型必须是char,byte,short,int,Character,Byte,Short,Integer,String或枚举类型(第8.9节),否则会发生编译时错误.

http://docs.oracle.com/javase/specs/jls/se7/html/jls-14.html#jls-14.11

  • 老实说,这是最好的答案.我不确定应该鼓励使原始问题发挥作用所需的体操类型. (8认同)

Bat*_*eba 50

您无法打开整个阵列.但是你可以转换成一个集合,牺牲了switch它自身的一些可读性:

switch (values[0] + 2 * values[1] + 4 * values[2] + 8 * values[3])

并在case语句中使用二进制文字:case 0b0101是你的第一个.

  • 为了使这个可扩展,我把它放在一个循环中:`int switchVal = 0; for(int i = 0; i <values.length(); i ++){switchVal + = values [i]?(2 << i):0; 然后打开`switchVal`变量. (5认同)
  • 为了使交换机更具可读性/有意义,可以考虑将每个二进制文字都设置为有意义的常量,这样就可以开启常量,而不是二进制文字. (3认同)
  • 这基本上是将`[true,false,true,false]`转换为'1010`位系列,可以"切换",对吗?绝对是去IMO的方式. (3认同)

Ale*_*lex 47

尝试此解决方案:

    boolean[] values = new boolean[4];
    values[0] = true;
    values[1] = false;
    values[2] = false;
    values[3] = true;

    if (ArrayUtils.isEquals(values, new boolean[] {true, false, true, false})) {
    ...
    }
    else if (ArrayUtils.isEquals(values, new boolean[] {false, false, true, false})) {
    ...
    }
    else {
    ...
    }
Run Code Online (Sandbox Code Playgroud)

请参阅此处的文档.

  • 他们命名了一个函数`isEquals` ?? (98认同)
  • 这是一个非常紧凑的阵列大小的解决方案,当阵列改变大小的那一刻,你将有一个维护噩梦. (50认同)
  • 不需要apache-commons-lang - 只需使用JDK中的`java.util.Arrays.equals(arr1,arr2)`. (10认同)
  • @drigoangelo:我知道我知道.但我想知道为什么他们不只是使用`isEqual`,所以要么是'动词形容词`或'动词名词`,而不是`动词动词`.就个人而言,我更喜欢`形容词`用于布尔函数,而`verb`用于改变状态的程序. (10认同)
  • @JonathanDrapeau,无论如何你都可能会遇到这种设计的维护噩梦...... (2认同)
  • `Arrays.equals`不需要第三方依赖吗? (2认同)

giv*_*nse 22

是的,您可以将数组传递给交换机.问题在于我不是在谈论Java数组,而是数据结构.

数组是对象的系统排列,通常是行和列.

您要做的是实现一个识别不同标志的系统,并根据打开或关闭的标志执行不同的操作.

这种机制的流行实现是Linux文件权限.你在哪里rwx作为"旗帜阵列".

如果整个数组都是真的,你会看到rwx,这意味着你拥有所有权限.如果你不允许对文件执行任何操作,那么整个数组都是假的,你会看到---.

履行

猜猜看,你可以将整数看作数组.整数由"位数组"表示.

001 // 1, if on, set x 
010 // 2, if on, set w 
100 // 4, if on, set r
// putting it all together in a single "array" (integer)
111 // 2^2 + 2^1 + 2^0 = 4 + 2 + 1 = 7
Run Code Online (Sandbox Code Playgroud)

这就是为什么许可rwx可以表示为a7

Java片段:

class Flags {                                                                    
public static void main(String args[]) {         
        /** 
         * Note the notation "0b", for binary; I'm using it for emphasis.
         * You could just do: 
         * byte flags = 6;
         */                     
        byte flags = 0b110; // 6                     
        switch(flags) {                                                          
            case 0: /* do nothing */ break;                                      
            case 3: /* execute and write */ break;                       
            case 6: System.out.println("read and write\n"); break;         
            case 7: /* grant all permissions */ break;                           
            default:                                                             
                System.out.println("invalid flag\n");           
        }                                                                        
    }                                                                            
}
Run Code Online (Sandbox Code Playgroud)

要了解有关使用二进制格式的更多信息,请检查以下问题:在Java中,我可以定义二进制格式的整数常量吗?

性能

  • 节省内存
  • 您不必进行额外的处理,开关或任何其他类型的杂耍.

需要尽可能高效的C程序使用这种机制; 它们使用以单比特表示的标志.


Ada*_*ion 21

不,你不能,但是你可以用以下(脏我承认)代码替换上面的代码:

boolean[] values = new boolean[4];

values[0] = true;
values[1] = false;
values[2] = false;
values[3] = true;

switch(makeSuitableForSwitch(values)) {
   case 1010: 
     break;
   case 10: 
     break;
   default:
     break;
} 

private int makeSuitableForSwitch( boolean[] values) {
    return (values[0]?1:0)*1000+(values[1]?1:0)*100+(values[2]?1:0)*10+(values[3]?1:0);
}
Run Code Online (Sandbox Code Playgroud)

  • 除了它是错误的事实之外它是错误的:`0010`被解释为八进制...... (8认同)
  • 我会将sum公式放入方法中,而不是直接放在`switch`语句中. (3认同)
  • @Alex helper方法应该是`private`;)而且`return int`不是一个好主意,因为对于大数组,这可能会溢出. (2认同)

bob*_*obo 9

如果您正在尝试确定一组条件是否为真,那么我将使用按位字段.

例如,

public class HelloWorld
{
  // These are the options that can be set.
  // They're final so treated as constants.
  static final int A=1<<0, B=1<<1, C=1<<2, D=1<<3 ;

  public static void main(String []args)
  {
    // Now I set my options to have A=true, B=true, C=true, D=false, effectively
    int options = A | B | C ;

    switch( options )
    {
      case (A):
        System.out.println( "just A" ) ;
        break ;
      case (A|B):
        System.out.println( "A|B" ) ;
        break ;
      case (A|B|C): // Final int is what makes this work
        System.out.println( "A|B|C" ) ;
        break ;
      default:
        System.out.println( "unhandled case" ) ;
        break ;
    }
  }
}
Run Code Online (Sandbox Code Playgroud)


Juv*_*nis 6

我根据布尔数组中元素的顺序计算一个值,即[true, false, true, true]计算到1011然后根据这个整数值你可以使用switch语句.