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

Java 在switch中使用数组作为case语句,java,arrays,switch-statement,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, f

我正在尝试这样做,即在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;
}

答案是否定的。最好的解释是学会如何使用。

,你不能

SwitchStatement:
    switch ( Expression ) SwitchBlock
表达式的类型必须是char、byte、short、int、Character、byte、short、Integer、String或枚举类型(§8.9),否则会发生编译时错误

尝试以下解决方案:

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

请参阅文档。

不,您不能,但是您可以用以下(我承认)代码替换上述代码:


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

您无法切换整个数组。但您可以转换为位集,但这会牺牲
开关本身的可读性:

开关(值[0]+2*值[1]+4*值[2]+8*值[3])


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

@sᴜʀᴇsʜᴀᴛᴛᴀ 这是对的。但我想补充一点。自Java7以来,switch语句支持字符串,因此您可以对其进行处理它真的很脏,我不建议这样做,但这样做有效:

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

对于那些关心性能的人来说:你是对的,这不是超快速的。这将被编译成如下内容:

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

是的,您可以将数组传递给交换机。关键是我不是在谈论Java数组,而是一种数据结构

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

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

示例

这种机制的一个流行实现是Linux文件权限。其中,
rwx
作为“标志数组”

如果整个数组为true,您将看到
rwx
,这意味着您拥有所有权限。如果不允许对文件执行任何操作,则整个数组为false,您将看到
--

实施

猜猜看,你可以把整数看作数组。整数由“位数组”表示

这就是为什么权限
rwx
可以表示为
7

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");           
        }                                                                        
    }                                                                            
}
要了解有关使用二进制格式的更多信息,请检查以下问题:

性能

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

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

如果您试图确定一组条件是否为真,我将使用按位字段

比如说,

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 ;
    }
  }
}
公共类HelloWorld
{
//这些是可以设置的选项。
//它们是最终的,所以被视为常数。

静态final int A=1这里是另一种不需要导入或库的方法:

boolean[] values = new boolean[4];

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

int mask = buildMask(values);

if (areEquals(mask, true, false, true, false)) {
    // ...
} else if (areEquals(mask, false, false, true, false)) {
    // ...
} else {
    // ...
}

private int buildMask(boolean... values) {
    int n = 0;
    for (boolean b : values) {
        n = (n << 1) | (b ? 1 : 0);
    }
    return n;
}

private boolean areEquals(int mask, boolean... values) {
    return mask == buildMask(values);
}
boolean[]值=新的boolean[4];
值[0]=真;
值[1]=假;
值[2]=假;
值[3]=真;
int mask=buildMask(值);
if(arequals(掩码、真、假、真、假)){
// ...
}else if(arequals(掩码、假、假、真、假)){
// ...
}否则{
// ...
}
私有int构建掩码(布尔值){
int n=0;
for(布尔b:值){

n=(n从JRE 1.7开始,您将需要使用hack,我建议:

  • 假设
    值(长度64)
    抛出新的非法状态异常();
    长位标志=0x0L;
    对于(int i=0;i
    我创建了一个可编译为Javascript和Flash的演示。您可以在右栏中看到js输出

    演示:

    这是一个输出开关,它使用嵌套开关。如果你玩这些案例,你会看到js输出是如何变化的,从而拥有一个高效的开关

    (function () { "use strict";
    var Test = function() { };
    Test.main = function() {
        var array = [true,false,true,false];
        var result;
        switch(array.length) {
        case 4:
            switch(array[0]) {
            case true:
                switch(array[1]) {
                case false:
                    switch(array[2]) {
                    case true:
                        switch(array[3]) {
                        case false:
                            result = "no";
                            break;
                        default:
                            result = "??";
                        }
                        break;
                    default:
                        result = "??";
                    }
                    break;
                default:
                    result = "??";
                }
                break;
            case false:
                switch(array[1]) {
                case false:
                    switch(array[2]) {
                    case true:
                        switch(array[3]) {
                        case false:
                            result = "yes";
                            break;
                        default:
                            result = "??";
                        }
                        break;
                    default:
                        result = "??";
                    }
                    break;
                default:
                    result = "??";
                }
                break;
            }
            break;
        default:
            result = "??";
        }
        new js.JQuery("body").html(result);
    };
    var js = {};
    var q = window.jQuery;
    js.JQuery = q;
    Test.main();
    })();
    
    另一个可以使用下划线的有趣模式。模式匹配任何内容,因此大小写等于默认值,这使您能够执行以下操作:

    var myArray = [1, 6];
    var match = switch(myArray) {
        case [2, _]: "0";
        case [_, 6]: "1";
        case []: "2";
        case [_, _, _]: "3";
        case _: "4";
    }
    trace(match); // 1
    

    您还可以看看Groovy是如何在Java中实现isCase()方法的,使用一个更简单的版本来满足您的需要。您可以将它放在一个接口中,并创建一个DSL来比较应用程序中的任意两个对象

    return isCase(DefaultTypeTransformation.asCollection(caseValue), switchValue);
    

    相关代码在至中介绍。我将使用表示布尔状态的常量int值

    如果使用Java1.7或更高版本,则可以使用可读性更强的二进制文本

    public static final int TRUE_FALSE_TRUE_FALSE = 0b1010;
    public static final int FALSE_FALSE_TRUE_FALSE = 0b0010;
    
    对于Java 1.6及以下版本,请使用任何其他int文本,例如十六进制

    public static final int TRUE_FALSE_TRUE_FALSE = 0xA;
    public static final int FALSE_FALSE_TRUE_FALSE = 0x2;
    
    然后创建一个将布尔数组转换为整数位集的方法

    public static int toIntBitSet(boolean...values){
        int bitset = 0;
        for (boolean value : values) {
           bitset = (bitset << 1) | (value ? 1 : 0);
        }
        return bitset;
    }
    
    另一种方法可能是使用java
    位集
    和映射到应根据位集值执行的逻辑的
    映射

    public static void main(String[] args) throws Exception {
      Map<BitSet, Callable<String>> bitSetMap = new HashMap<>();
    
      bitSetMap.put(bitSetValueOf(true, false, true, false), new TrueFalseTrueFalseCallable());
      bitSetMap.put(bitSetValueOf(false, false, true, false), new FalseFalseTrueFalseCallable());
    
      boolean[] values = new boolean[]{true, false, true, false};
    
      BitSet bitset = bitSetValueOf(values);
    
      Callable<String> callable = bitSetMap.get(bitset);
      if (callable == null) {
        callable = new DefaultCallable();
      }
    
      String result = callable.call();
      System.out.println(result);
    }
    
    public static BitSet bitSetValueOf(boolean... values) {
       BitSet bitSet = new BitSet();
          for (int i = 0; i < values.length; i++) {
             bitSet.set(i, values[i]);
          }
       return bitSet;
    }
    
    publicstaticvoidmain(字符串[]args)引发异常{
    Map bitSetMap=newhashmap();
    put(bitSetValueOf(true,false,true,false),new-truefalseCallable());
    put(bitSetValueOf(false,false,true,false),new falseCallable());
    布尔[]值=新的布尔[]{true,false,true,false};
    BitSet BitSet=bitSetValueOf(值);
    Callable Callable=bitSetMap.get(位集);
    if(可调用==null){
    callable=新的DefaultCallable();
    }
    String result=callable.call();
    系统
    
    public static final int TRUE_FALSE_TRUE_FALSE = 0b1010;
    public static final int FALSE_FALSE_TRUE_FALSE = 0b0010;
    
    public static final int TRUE_FALSE_TRUE_FALSE = 0xA;
    public static final int FALSE_FALSE_TRUE_FALSE = 0x2;
    
    public static int toIntBitSet(boolean...values){
        int bitset = 0;
        for (boolean value : values) {
           bitset = (bitset << 1) | (value ? 1 : 0);
        }
        return bitset;
    }
    
    boolean[] values = new boolean[]{true, false, true, false};
    
    int bitset = toIntBitSet(values);
    
    switch (bitset) {
      case TRUE_FALSE_TRUE_FALSE:
        System.out.println(Integer.toBinaryString(bitset));
        break;
      case FALSE_FALSE_TRUE_FALSE:
        System.out.println(Integer.toBinaryString(bitset));
        break;
      default:
        break;
    }
    
    public static void main(String[] args) throws Exception {
      Map<BitSet, Callable<String>> bitSetMap = new HashMap<>();
    
      bitSetMap.put(bitSetValueOf(true, false, true, false), new TrueFalseTrueFalseCallable());
      bitSetMap.put(bitSetValueOf(false, false, true, false), new FalseFalseTrueFalseCallable());
    
      boolean[] values = new boolean[]{true, false, true, false};
    
      BitSet bitset = bitSetValueOf(values);
    
      Callable<String> callable = bitSetMap.get(bitset);
      if (callable == null) {
        callable = new DefaultCallable();
      }
    
      String result = callable.call();
      System.out.println(result);
    }
    
    public static BitSet bitSetValueOf(boolean... values) {
       BitSet bitSet = new BitSet();
          for (int i = 0; i < values.length; i++) {
             bitSet.set(i, values[i]);
          }
       return bitSet;
    }
    
    class FalseFalseTrueFalseCallable implements Callable<String> {
    
      @Override
      public String call() throws Exception {
        return "0010";
      }
    
    }
    
    class TrueFalseTrueFalseCallable implements Callable<String> {
    
      @Override
      public String call() throws Exception {
        return "1010";
      }
    
    }
    
    class DefaultCallable implements Callable<String> {
    
      @Override
      public String call() throws Exception {
        return "default value";
      }
    
    }
    
    boolean[] values = new boolean[4];
    
    values[0] = true;
    values[1] = false;
    values[2] = false;
    values[3] = true;
    
    values = Arrays.toString(values)
    
    switch (values) {
        case "[true, false, true, false]":
            break;
        case "[false, false, true, false]":
            break;
        case "[true, false, false, true]":
            System.out.println("YAAAAAAAAAA GOT IT");
            break;
        default:
            break;
    }