스위치에서 케이스 문으로 배열 사용
나는 이와 같은 것을 시도하고있다. 즉, 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
Expression 형식은 char, byte, short, int, Character, Byte, Short, Integer, String 또는 enum 형식 (§8.9)이어야하며 그렇지 않으면 컴파일 타임 오류가 발생합니다.
http://docs.oracle.com/javase/specs/jls/se7/html/jls-14.html#jls-14.11
@ sᴜʀᴇsʜ ᴀᴛᴛᴀ이 맞습니다. 하지만 뭔가를 추가하고 싶었습니다. Java 7부터 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;
}
전체 어레이를 켤 수 없습니다. 그러나 약간의 가독성을 희생시키면서 비트 세트로 변환 할 수switch
있습니다.
switch (values[0] + 2 * values[1] + 4 * values[2] + 8 * values[3])
case 문에 이진 리터럴 을 사용 case 0b0101
하십시오. 첫 번째입니다.
이 솔루션을 시도하십시오.
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 {
...
}
예, 어레이를 스위치에 전달할 수 있습니다. 문제는 제가 Java 배열에 대해 말하는 것이 아니라 데이터 구조라는 것입니다.
배열은 일반적으로 행과 열로 된 객체의 체계적인 배열입니다.
당신이하려는 것은 다른 플래그를 인식하는 시스템을 구현하고 켜거나 끄는 플래그에 따라 다른 조치를 취하는 것입니다.
예
이러한 메커니즘의 일반적인 구현은 Linux 파일 권한입니다. rwx
"플래그의 배열"로있는 곳 .
전체 배열이 true이면 rwx
모든 권한이 있음을 의미하는이 표시됩니다. 파일에 대해 어떤 작업도 수행 할 수없는 경우 전체 배열이 false이고 ---
.
이행
정수를 배열로 생각할 수 있습니다. 정수는 "비트 배열"로 표시됩니다.
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
그렇기 때문에 권한 rwx
은7
자바 스 니펫 :
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");
}
}
}
이진 형식 사용에 대한 자세한 내용은 다음 질문을 확인하십시오 . Java에서 이진 형식으로 정수 상수를 정의 할 수 있습니까?
공연
- 메모리 절약
- 추가 처리, 스위치 또는 기타 유형의 저글링을 수행 할 필요가 없습니다.
가능한 한 효율적이어야하는 C 프로그램은 이러한 유형의 메커니즘을 사용합니다. 단일 비트로 표시된 플래그를 사용합니다.
아니요, 할 수는 없지만 위의 코드를 다음 (더럽게 인정합니다) 코드로 바꿀 수 있습니다.
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);
}
조건 집합 이 참 인지 확인하려는 경우 대신 비트 필드를 사용합니다.
예를 들면
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 ;
}
}
}
부울 배열의 요소 시퀀스를 기반으로 값을 계산합니다. 즉, [true, false, true, true]
1011로 평가 한 다음이 정수 값을 기반으로 switch 문을 사용할 수 있습니다.
내 대답은 아니오 야. 가장 좋은 설명은 switch 문 을 사용 하는 방법을 배우는 것 입니다.
JRE 1.7부터는 해킹을 사용해야합니다. 다음을 권장합니다.
취하다
values.length <= 64
값을
long
나타내는 비트 플래그로 변환Switch
16 진수 매직 넘버 에 대해
자바 코드 해킹 :
if(values.length > 64)
throw new IllegalStateException();
long bitflags = 0x0L;
for(int i=0; i< values.length; ++i)
if(values[i])
bitflags |= 0x01L << i;
switch(bitflags) {
case 0xEL: // represents [true, true, true, false]
break;
case 0xAL: // represents [true, false, true, false]
break;
case 0x2L: // represents [false, false, true, false]
break;
default:
break;
}
다음은 가져 오기 나 라이브러리가 필요없는 또 다른 방법입니다.
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);
}
이 대답은 Java 가 아니지만 Haxe는 패턴 일치 덕분에 가능하고 흥미로운 출력을 가지고 있기 때문에 원하는 것을 수행하는 스위치를 찾는 데 유용 할 수 있습니다. 배열은 고정 길이로 일치시킬 수 있습니다.
Javascript와 Flash로 컴파일되는 데모를 만들었습니다. 오른쪽 열에서 js 출력을 볼 수 있습니다.
데모 : http://try.haxe.org/#86314
class Test {
static function main(){
var array=[true,false,true];
var result=switch(array){
case [true,true,false]: "no";
case [true,false,true]: "yes";
default:"??";
}
#if js
new js.JQuery("body").html(result);
#elseif flash
trace(result);
#end
// ouputs: "yes"
}
}
이것은 출력 스위치이며 중첩 스위치를 사용합니다. 케이스를 가지고 놀면 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();
})();
밑줄을 사용할 수있는 또 다른 흥미로운 패턴입니다. _ 패턴은 모든 항목과 일치하므로 case _ :는 기본값과 동일하므로 다음을 수행 할 수 있습니다.
var myArray = [1, 6];
var match = switch(myArray) {
case [2, _]: "0";
case [_, 6]: "1";
case []: "2";
case [_, _, _]: "3";
case _: "4";
}
trace(match); // 1
http://haxe.org/manual/pattern_matching#array-matching
또한 Groovy가 Java에서 isCase () 메서드를 구현하는 방법을 살펴보고 필요에 맞는 더 간단한 버전을 사용할 수 있습니다. 이를 인터페이스에 넣고 DSL을 만들어 애플리케이션의 두 개체를 비교할 수 있습니다.
return isCase(DefaultTypeTransformation.asCollection(caseValue), switchValue);
관련 코드는 877 행에서 982 행 까지 적용됩니다.
@Todor 네, JAVA에서 가능합니다.
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;
}
참고 : 저는 자바 개발자가 아니므로 코드 구문이 잘못 될 수 있지만 논리는 완벽합니다. 내 대답을 편집 할 수 있습니다. 여기에서 배열을 문자열 형식으로 변환 한 다음 대 / 소문자를 일치 시키려고했습니다.
부울 상태를 나타내는 상수 int 값을 사용합니다.
당신이 사용하는 경우 자바 1.7 또는 이상 당신은 바이너리 리터럴 사용할 수 있습니다 더 읽기를 .
public static final int TRUE_FALSE_TRUE_FALSE = 0b1010;
public static final int FALSE_FALSE_TRUE_FALSE = 0b0010;
for Java 1.6 and below use any other int literals, e.g. hex
public static final int TRUE_FALSE_TRUE_FALSE = 0xA;
public static final int FALSE_FALSE_TRUE_FALSE = 0x2;
then create a method that converts a boolean array to an integer bitset. E.g.
public static int toIntBitSet(boolean...values){
int bitset = 0;
for (boolean value : values) {
bitset = (bitset << 1) | (value ? 1 : 0);
}
return bitset;
}
Finally use the constants in your switch statement
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;
}
Another approach might be to use a java BitSet
and a Map
that maps to the logic that should be executed depending on the bitset's value.
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;
}
and implement your logic
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";
}
}
참고URL : https://stackoverflow.com/questions/20659979/use-an-array-as-a-case-statement-in-switch
'Nice programing' 카테고리의 다른 글
MVC 유효성 검사에 대한 단위 테스트 (0) | 2020.10.17 |
---|---|
UICollectionView는 상단 여백 추가 (0) | 2020.10.17 |
PHP에서 날짜 시간에 분 추가 (0) | 2020.10.17 |
종료를 호출 한 후 핸드 셰이크를 대기열에 넣을 수 없습니다. (0) | 2020.10.17 |
Android / Java-날짜 차이 (일) (0) | 2020.10.17 |