Pregunta Use una matriz como una declaración de caso en el interruptor


Intento hacer algo como esto, es decir, usar una matriz en una declaración de cambio. ¿Es posible en Java? Si no es así, explique una posible solución.

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

73
2017-12-18 13:50


origen


Respuestas:


NOsimplemente no puedes.

SwitchStatement:
    switch ( Expression ) SwitchBlock

El tipo de Expression debe ser char, byte, short, int, Character, Byte, Short, Integer, String o un tipo de enumeración (§8.9), o se produce un error en tiempo de compilación.

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


63
2017-12-18 13:52



@ sᴜʀᴇsʜ ᴀᴛᴛᴀ tiene razón. Pero quería agregar algo. Desde Java 7, las instrucciones switch admiten cadenas, por lo que podría hacer algo con eso. Está realmente sucio y no lo recomiendo, pero esto funciona:

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

Para aquellos preocupados por el rendimiento: tienes razón, esto no es súper rápido. Esto se compilará en algo como esto:

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

73
2017-12-18 14:01



No puedes encender arreglos completos. Pero tu podría convertir a un bit establecido a expensas de cierta legibilidad de la switch sí mismo:

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

y use literales binarios en sus declaraciones de casos: case 0b0101 es tu primera persona


50
2017-12-18 13:57



Prueba esta solución:

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

Ver documentos aquí.


47
2017-12-18 13:53



Sí, puedes pasar una matriz a un interruptor. El problema es que no estoy hablando de matrices de Java, sino de una estructura de datos.

Una matriz es una disposición sistemática de objetos, generalmente en filas y columnas.

Lo que intenta hacer es implementar un sistema que reconozca diferentes banderas y, dependiendo de los indicadores que estén activados o desactivados, realice diferentes acciones.

Ejemplo

Una implementación popular de dicho mecanismo es permisos de archivos de Linux. Donde tienes rwx como el "conjunto de banderas".

Si toda la matriz es verdadera, verás rwx, lo que significa que tienes todos los permisos. Si no puede realizar ninguna acción en un archivo, toda la matriz es falsa, verá ---.

Implementación

Adivina qué, puedes pensar en enteros como matrices. Un número entero está representado por una "matriz de bits".

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

Es por eso que el permiso rwx puede ser representado como un 7

Fragmento de código 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");           
        }                                                                        
    }                                                                            
}

Para saber más sobre el uso de un formato binario, verifique esta pregunta: En Java, ¿puedo definir una constante entera en formato binario?

Actuación

  • Guarda memoria
  • No tiene que hacer procesamiento adicional, interruptores ni ningún otro tipo de malabares.

Los programas C que requieren ser lo más eficientes posible utilizan este tipo de mecanismo; usan banderas representadas con bits individuales.


21
2017-12-18 15:48



No, no puedes, sin embargo puedes reemplazar lo anterior con el siguiente código (sucio, lo admito):

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

20
2017-12-18 13:54



Si estás tratando de determinar si conjunto de condiciones es cierto, usaría campos bit a bit en su lugar.

Por ejemplo,

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

9
2017-12-18 19:43



Calculo un valor basado en la secuencia de los elementos en la matriz booleana, es decir [true, false, true, true] evaluaría a 1011 y luego, basado en este valor entero, puede usar la declaración de cambio.


6
2017-12-18 13:55