Hanya mencoba untuk mencari tahu bagaimana menggunakan banyak beberapa kasus untuk Java pernyataan switch. Berikut ini's contoh dari apa yang saya'm mencoba untuk melakukan:
switch (variable)
{
case 5..100:
doSomething();
break;
}
dibandingkan harus melakukan:
switch (variable)
{
case 5:
case 6:
etc.
case 100:
doSomething();
break;
}
Ide jika ini mungkin, atau apa alternatif yang baik adalah?
Pilihan kedua adalah yang benar-benar baik-baik saja. I'm tidak yakin mengapa responden mengatakan hal itu tidak mungkin. Ini baik-baik saja, dan aku melakukan hal ini sepanjang waktu:
switch (variable)
{
case 5:
case 6:
etc.
case 100:
doSomething();
break;
}
Mungkin tidak elegan seperti beberapa jawaban sebelumnya, tetapi jika anda ingin untuk mencapai beralih kasus dengan beberapa rentang besar, hanya menggabungkan berkisar pada satu hal terlebih dahulu:
// make a switch variable so as not to change the original value
int switchVariable = variable;
//combine range 1-100 to one single case in switch
if(1 <= variable && variable <=100)
switchVariable = 1;
switch (switchVariable)
{
case 0:
break;
case 1:
// range 1-100
doSomething();
break;
case 101:
doSomethingElse();
break;
etc.
}
public class SwitchTest {
public static void main(String[] args){
for(int i = 0;i<10;i++){
switch(i){
case 1: case 2: case 3: case 4: //First case
System.out.println("First case");
break;
case 8: case 9: //Second case
System.out.println("Second case");
break;
default: //Default case
System.out.println("Default case");
break;
}
}
}
}
Keluar:
Default case
First case
First case
First case
First case
Default case
Default case
Default case
Second case
Second case
Src: http://docs.oracle.com/javase/tutorial/java/nutsandbolts/switch.html
Satu Object Oriented pilihan untuk menggantikan terlalu besar switch
dan if/else
konstruksi adalah dengan menggunakan Rantai tanggung Jawab Pola
untuk model pengambilan keputusan.
Rantai tanggung Jawab Pola
rantai tanggung jawab pola memungkinkan pemisahan sumber permintaan dari memutuskan yang mana dari berpotensi besar jumlah penangan untuk permintaan tindakan itu. Yang kelas yang mewakili rantai peran saluran permintaan dari sumber beserta daftar penangan sampai handler menerima permintaan dan tindakan itu.
Berikut adalah contoh implementasi yang juga Tipe Aman dengan menggunakan obat Generik.
import java.util.ArrayList;
import java.util.List;
/**
* Generic enabled Object Oriented Switch/Case construct
* @param <T> type to switch on
*/
public class Switch<T extends Comparable<T>>
{
private final List<Case<T>> cases;
public Switch()
{
this.cases = new ArrayList<Case<T>>();
}
/**
* Register the Cases with the Switch
* @param c case to register
*/
public void register(final Case<T> c) { this.cases.add(c); }
/**
* Run the switch logic on some input
* @param type input to Switch on
*/
public void evaluate(final T type)
{
for (final Case<T> c : this.cases)
{
if (c.of(type)) { break; }
}
}
/**
* Generic Case condition
* @param <T> type to accept
*/
public static interface Case<T extends Comparable<T>>
{
public boolean of(final T type);
}
public static abstract class AbstractCase<T extends Comparable<T>> implements Case<T>
{
protected final boolean breakOnCompletion;
protected AbstractCase()
{
this(true);
}
protected AbstractCase(final boolean breakOnCompletion)
{
this.breakOnCompletion = breakOnCompletion;
}
}
/**
* Example of standard "equals" case condition
* @param <T> type to accept
*/
public static abstract class EqualsCase<T extends Comparable<T>> extends AbstractCase<T>
{
private final T type;
public EqualsCase(final T type)
{
super();
this.type = type;
}
public EqualsCase(final T type, final boolean breakOnCompletion)
{
super(breakOnCompletion);
this.type = type;
}
}
/**
* Concrete example of an advanced Case conditional to match a Range of values
* @param <T> type of input
*/
public static abstract class InRangeCase<T extends Comparable<T>> extends AbstractCase<T>
{
private final static int GREATER_THAN = 1;
private final static int EQUALS = 0;
private final static int LESS_THAN = -1;
protected final T start;
protected final T end;
public InRangeCase(final T start, final T end)
{
this.start = start;
this.end = end;
}
public InRangeCase(final T start, final T end, final boolean breakOnCompletion)
{
super(breakOnCompletion);
this.start = start;
this.end = end;
}
private boolean inRange(final T type)
{
return (type.compareTo(this.start) == EQUALS || type.compareTo(this.start) == GREATER_THAN) &&
(type.compareTo(this.end) == EQUALS || type.compareTo(this.end) == LESS_THAN);
}
}
/**
* Show how to apply a Chain of Responsibility Pattern to implement a Switch/Case construct
*
* @param args command line arguments aren't used in this example
*/
public static void main(final String[] args)
{
final Switch<Integer> integerSwitch = new Switch<Integer>();
final Case<Integer> case1 = new EqualsCase<Integer>(1)
{
@Override
public boolean of(final Integer type)
{
if (super.type.equals(type))
{
System.out.format("Case %d, break = %s\n", type, super.breakOnCompletion);
return super.breakOnCompletion;
}
else
{
return false;
}
}
};
integerSwitch.register(case1);
// more instances for each matching pattern, granted this will get verbose with lots of options but is just
// and example of how to do standard "switch/case" logic with this pattern.
integerSwitch.evaluate(0);
integerSwitch.evaluate(1);
integerSwitch.evaluate(2);
final Switch<Integer> inRangeCaseSwitch = new Switch<Integer>();
final Case<Integer> rangeCase = new InRangeCase<Integer>(5, 100)
{
@Override
public boolean of(final Integer type)
{
if (super.inRange(type))
{
System.out.format("Case %s is between %s and %s, break = %s\n", type, this.start, this.end, super.breakOnCompletion);
return super.breakOnCompletion;
}
else
{
return false;
}
}
};
inRangeCaseSwitch.register(rangeCase);
// run some examples
inRangeCaseSwitch.evaluate(0);
inRangeCaseSwitch.evaluate(10);
inRangeCaseSwitch.evaluate(200);
// combining both types of Case implementations
integerSwitch.register(rangeCase);
integerSwitch.evaluate(1);
integerSwitch.evaluate(10);
}
}
Ini adalah hanya cepat jerami pria yang aku dikocok sampai dalam beberapa menit, yang lebih canggih implementasi mungkin memungkinkan untuk beberapa jenis Perintah Pola
yang akan disuntikkan ke dalam Kasus
implementasi contoh untuk membuatnya lebih dari sebuah panggilan kembali IoC gaya.
Sekali hal yang baik tentang pendekatan ini adalah bahwa Switch/laporan Kasus ini adalah semua tentang mempengaruhi sisi, ini merangkum efek samping di Kelas sehingga mereka dapat dikelola, dan digunakan kembali baik, itu berakhir menjadi lebih seperti Pencocokan Pola dalam bahasa Fungsional dan bahwa isn't hal yang buruk.
Saya akan posting setiap update atau tambahan untuk ini Inti pada Github.
Menurut pertanyaan, it's benar-benar mungkin.
Hanya menempatkan semua kasus-kasus yang mengandung logika yang sama bersama-sama, dan don't menempatkan istirahat
di belakang mereka.
switch (var) {
case (value1):
case (value2):
case (value3):
//the same logic that applies to value1, value2 and value3
break;
case (value4):
//another logic
break;
}
It's karena kasus
tanpa istirahat
akan melompat ke yang lain kasus
sampai break
atau kembali
.
EDIT:
Membalas komentar, jika kita benar-benar memiliki nilai-nilai 95 dengan logika yang sama, tetapi cara yang lebih kecil jumlah kasus dengan logika yang berbeda, yang bisa kita lakukan:
switch (var) {
case (96):
case (97):
case (98):
case (99):
case (100):
//your logic, opposite to what you put in default.
break;
default:
//your logic for 1 to 95. we enter default if nothing above is met.
break;
}
Jika anda membutuhkan kontrol yang lebih baik, if-else
adalah pilihan.
Pada dasarnya:
if (variable >= 5 && variable <= 100)
{
doSomething();
}
Jika anda benar-benar perlu menggunakan switch, itu akan karena anda perlu melakukan berbagai hal untuk rentang tertentu. Dalam kasus itu, ya, kau're akan memiliki kode berantakan, karena hal-hal yang semakin kompleks dan hanya hal-hal yang mengikuti pola akan kompres dengan baik.
Satu-satunya alasan untuk beralih adalah untuk menghemat mengetik nama variabel jika anda're hanya pengujian untuk numerik switching nilai-nilai. Anda tidak't akan beralih pada 100 hal, dan mereka tidak't akan melakukan hal yang sama. Itu lebih terdengar seperti 'jika' chunk.
// Noncompliant Contoh Kode
switch (i) {
case 1:
doFirstThing();
doSomething();
break;
case 2:
doSomethingDifferent();
break;
case 3: // Noncompliant; duplicates case 1's implementation
doFirstThing();
doSomething();
break;
default:
doTheRest();
}
if (a >= 0 && a < 10) {
doFirstThing();
doTheThing();
}
else if (a >= 10 && a < 20) {
doTheOtherThing();
}
else if (a >= 20 && a < 50) {
doFirstThing();
doTheThing(); // Noncompliant; duplicates first condition
}
else {
doTheRest();
}
//Solusi Compliant
switch (i) {
case 1:
case 3:
doFirstThing();
doSomething();
break;
case 2:
doSomethingDifferent();
break;
default:
doTheRest();
}
if ((a >= 0 && a < 10) || (a >= 20 && a < 50)) {
doFirstThing();
doTheThing();
}
else if (a >= 10 && a < 20) {
doTheOtherThing();
}
else {
doTheRest();
}
Hal ini dimungkinkan untuk menangani ini menggunakan Vavr perpustakaan
import static io.vavr.API.*;
import static io.vavr.Predicates.*;
Match(variable).of(
Case($(isIn(5, 6, ... , 100)), () -> doSomething()),
Case($(), () -> handleCatchAllCase())
);
Hal ini tentu saja hanya sedikit perbaikan karena semua kasus yang masih perlu tercantum secara eksplisit. Tapi itu mudah untuk mendefinisikan custom predikat:
public static <T extends Comparable<T>> Predicate<T> isInRange(T lower, T upper) {
return x -> x.compareTo(lower) >= 0 && x.compareTo(upper) <= 0;
}
Match(variable).of(
Case($(isInRange(5, 100)), () -> doSomething()),
Case($(), () -> handleCatchAllCase())
);
Pertandingan ekspresi jadi di sini itu kembali sesuatu seperti Runnable
contoh bukan menerapkan metode ini diatas. Setelah pertandingan yang dilakukan Runnable
dapat dieksekusi.
Untuk rincian lebih lanjut silakan lihat dokumentasi resmi.
Dari terakhir java-12 rilis beberapa konstanta dalam kasus yang sama label tersedia di preview fitur bahasa
tersedia dalam JDK rilis fitur untuk memprovokasi pengembang umpan balik berdasarkan dunia nyata digunakan; hal ini dapat menyebabkan ia menjadi permanen di masa depan Java SE Platform.
Itu terlihat seperti:
switch(variable) {
case 1 -> doSomething();
case 2, 3, 4 -> doSomethingElse();
};
Lihat lebih banyak JEP 325: Beralih Ekspresi (Preview)
Salah satu alternatif daripada menggunakan hard-coded nilai-nilai yang bisa menggunakan berbagai pemetaan pada pernyataan switch sebagai gantinya:
private static final int RANGE_5_100 = 1;
private static final int RANGE_101_1000 = 2;
private static final int RANGE_1001_10000 = 3;
public boolean handleRanges(int n) {
int rangeCode = getRangeCode(n);
switch (rangeCode) {
case RANGE_5_100: // doSomething();
case RANGE_101_1000: // doSomething();
case RANGE_1001_10000: // doSomething();
default: // invalid range
}
}
private int getRangeCode(int n) {
if (n >= 5 && n <= 100) {
return RANGE_5_100;
} else if (n >= 101 && n <= 1000) {
return RANGE_101_1000;
} else if (n >= 1001 && n <= 10000) {
return RANGE_1001_10000;
}
return -1;
}