Jawa switch pernyataan beberapa kasus

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?

Mengomentari pertanyaan (1)
Larutan

Sayangnya, hal's tidak mungkin di pulau Jawa. Anda'll harus resor untuk menggunakan if-else pernyataan.

Komentar (16)

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;
}
Komentar (6)

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 
Komentar (1)

public class SwitchTest {
    public static void main(String[] args){
        for(int i = 0;i
Komentar (3)

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  type to switch on
*/
public class Switch
{
    private final List cases;

    public Switch()
    {
        this.cases = new ArrayList();
    }

    /**
     * Register the Cases with the Switch
     * @param c case to register
     */
    public void register(final Case 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 c : this.cases)
        {
            if (c.of(type)) { break; }
        }
    }

    /**
     * Generic Case condition
     * @param  type to accept
     */
    public static interface Case
    {
        public boolean of(final T type);
    }

    public static abstract class AbstractCase implements Case
    {
        protected final boolean breakOnCompletion;

        protected AbstractCase()
        {
            this(true);
        }

        protected AbstractCase(final boolean breakOnCompletion)
        {
            this.breakOnCompletion = breakOnCompletion;
        }
    }

    /**
     * Example of standard "equals" case condition
     * @param  type to accept
     */
    public static abstract class EqualsCase extends AbstractCase
    {
        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  type of input
     */
    public static abstract class InRangeCase extends AbstractCase
    {
        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 integerSwitch = new Switch();
        final Case case1 = new EqualsCase(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 inRangeCaseSwitch = new Switch();
        final Case rangeCase = new InRangeCase(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.

Komentar (1)

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.

Komentar (2)

Pada dasarnya:


if (variable >= 5 && variable 
Komentar (0)

// 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();
}
Komentar (2)

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  Predicate isInRange(T lower, T upper) {
    return x -> x.compareTo(lower) >= 0 && x.compareTo(upper)  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.

Komentar (0)

untuk alternatif, anda dapat menggunakan seperti di bawah ini:


if (variable >= 5 && variable 
Komentar (0)

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)

Komentar (0)

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 = 101 && n = 1001 && n 
Komentar (0)