statement - multiple if else java



بيان IF منظف (12)

في Java ، العبارة التالية تبدو فوضوية للغاية عندما يكون لديك الكثير من المصطلحات:

if(a.equals("x") || a.equals("y") || a.equals("z") || Any number of terms...... )
    //Do something

هل هناك طريقة أنظف لتنفيذ نفس الإجراء ، أود أن تكون شفرتي قابلة للقراءة قدر الإمكان.

ملاحظة: x، y و z هي عناصر نائبة فقط لأي سلسلة من أي طول. يمكن أن يكون هناك 20 حرفًا متسلسلًا هنا بطول متغير في حالة إذا كان كل شرط يتم إجراؤه معًا

شكر

https://src-bin.com


Answer #1

الوصول لعلم الدلالة

على المستوى الدلالي ، ما يتم التحقق منه هو تعيين العضوية . ومع ذلك ، يمكنك تنفيذه على مستوى منخفض للغاية ، مما يبيّن أساسًا جميع التعليمات البرمجية اللازمة لتحقيق الشيك. بصرف النظر عن إجبار القارئ على استنتاج القصد من وراء هذه الحالة الهائلة ، فإن القضية البارزة في مثل هذا النهج هي العدد الكبير من درجات الحرية في تعبير بولياني عام: للتأكد من أن كل شيء يصل إلى مجرد التحقق من العضوية المحددة ، يجب فحص كل بند بعناية ، مع مراعاة أي قوسين ، والأخطاء الإملائية لاسم المتكرر المتكرر ، والمزيد.

كل درجة فضفاضة من الحرية تعني التعرض ليس فقط لعلة واحدة أخرى ، ولكن لفئة أخرى من البق.

النهج الذي يستخدم مجموعة واضحة سيكون له هذه المزايا:

  • دلالات واضحة وصريحة.
  • قيود صارمة على درجات الحرية في الاعتناء بها ؛
  • O (1) تعقيد الزمن مقابل O (n) تعقيد كودك.

هذه هي الشفرة اللازمة لتنفيذ صيغة قائمة على مجموعة:

static final Set<String> matches = 
                            unmodifiableSet(new HashSet<>(asList("a","b","c")));
...

if (matches.contains(a)) // do something;

* أنا تشير إلى import static java.util.Arrays.asList import static java.util.Collections.unmodifiableSet


Answer #2

قابلية القراءة في الغالب التنسيق

لا يمكن قراءتها...

if(a.equals("x") || a.equals("y") || a.equals("z") || Any number of terms...... )
    //Do something

الآن من السهل إلى الحقيقي ...

if(a.equals("x") || 
   a.equals("y") || 
   a.equals("z") ||
   Any number of terms...... )
    //Do something

القراءة هي ذاتية للغاية بالنسبة للشخص قراءة التعليمات البرمجية المصدر.

إذا صادفت كودًا يطبق المجموعات أو الحلقات أو أحد الأجوبة المعقدة الأخرى هنا. كنت أهز رأسي في كفر.

افصل المنطق عن المشكلة

أنت تخلط شيئين مختلفين. هناك مشكلة في جعل منطق الأعمال سهل القراءة ، ومشكلة تطبيق منطق الأعمال.

 if(validState(a))
     // Do something

كيف تقوم بتنفيذ validState لا يهم. ما هو مهم هو أن التعليمة البرمجية ذات العبارة if قابلة للقراءة كمنهج عمل . لا ينبغي أن يكون سلسلة طويلة من العمليات المنطقية التي تخفي نية ما يحدث.

في ما يلي مثال لمنطق العمل المقروء .

if(!isCreditCard(a)) {
    return false;
}
if(isExpired(a)) {
    return false;
}
return paymentAuthorized(a);

على مستوى ما ، يجب أن يكون هناك كود يقوم بمعالجة المنطق الأساسي ، السلاسل ، المصفوفات ، إلخ ... إلخ. ولكن لا ينبغي أن يكون على هذا المستوى.

إذا وجدت أن عليك غالباً أن تتحقق مما إذا كانت السلسلة مساوية لمجموعة من السلاسل الأخرى. ضع هذا الرمز في فئة الأداة المساعدة سلسلة. فصله عن عملك والحفاظ على التعليمات البرمجية الخاصة بك قابلة للقراءة. من خلال التأكد من إظهار ما تحاول فعله حقًا.


Answer #3

أعتقد أن الطريقة الأنظف والأسرع هي وضع القيم في مجموعة.

String[] values={"value1","value2","value3"};
for (string value : values) {
    if (a.equals(value){
        //Some code
    }
}

Answer #4

أنا أفضل استخدام regexp مثل قليل من guys كتب العلوي. ولكن يمكنك أيضًا استخدام الرمز التالي

private boolean isOneMoreEquals(Object arg, Object... conditions) {
    if (conditions == null || arg == null) {
        return false;
    }
    for (int i = 0, d = conditions.length; i < d; i++) {
        if (arg.equals(conditions[i])) {
            return true;
        }
    }
    return false;
}

لذا سيكون كودك التالي:

if (isOneMoreEquals(a, "x", "y", "z") {
    //do something
}

Answer #5

إذا افترضنا أن "x" و "y" و "z" يمكن أن تكون ذات طول تعسفي ، فيمكنك استخدامها

if (0 <= java.util.Arrays.binarySearch(new String[] { "x", "y", "z" }, a)) {
    // Do something
}

فقط تأكد من أن قائمة العناصر الخاصة بك في ترتيب معجمي ، كما هو مطلوب من قبل binarySearch() . يجب أن يكون هذا متوافقًا تمامًا مع جافا 1.2 ، ويجب أن يكون أكثر كفاءة من الحلول التي تستخدم مجموعات جافا.

بالطبع ، إذا كانت "x" و "y" و "z" هي كل الحروف المفردة ، و a هي أيضًا شخصية ، يمكنك استخدامها if (0 <= "xyz".indexOf(a)) { ... } أو

switch (a) {
  case 'x': case 'y': case 'z':
    // Do something
}

Answer #6

إذا تم ضمان أن يكون طوله 1 ، فيمكنك القيام بما يلي:

if ("xyz".indexOf(a) != -1)

Answer #7

استخدم تعبير عادي

If (a.matches("[xyz]")){
    // matches either "x", "y", or "z"

أو ، لسلاسل أطول ،

If (a.matches("one|two|three")){
    // matches either "one", "two" or "three"

ولكن هذا أمر مكلف من الناحية الحسابية ، ولكن ربما ليس أسوأ بكثير من إنشاء set وما إلى ذلك. ولكنها أوضح طريقة يمكن أن أفكر بها.

ولكن في النهاية ، قد يكون من أجمل طريقة ترك الأشياء كما هي ، مع تعديل التنسيق:

if (a.equals("x") || 
    a.equals("y") || 
    a.equals("z")
    ){

لا يوجد أي غموض على الإطلاق في ما تقوم به الكودات وبالتالي سيسهل الحفاظ على كودك. إذا كان هناك أهمية للأداء ، فيمكنك وضع التواجدات الأكثر احتمالًا في الجزء العلوي من القائمة.


Answer #8

بدلاً من ذلك ، إذا كنت تستخدم Java 7+ ، فيمكنك استخدام السلاسل في مفتاح التبديل / الحالة. على سبيل المثال (قمت باستخراج هذا من مستند Oracle وتعديله)

         switch (str) {

             case "x":
             case "y":
             case "z":
                 //do action
                 break;
             default:
              throw new IllegalArgumentException("argument not matched "+str);

    }

هنا هو link


Answer #9

ما رأيك يبدو "غير نظيفة" حول هذا الموضوع؟

إذا كان لديك مجموعة من المنطق المنطقي المعقد ، يمكنك فصل الأجزاء المختلفة منه إلى متغيرات منطقية فردية والإشارة إليها في بيان if.

أو يمكنك إنشاء دالة تأخذ المتغير 'a' وترجع قيمة منطقية. ستقوم فقط بإخفاء المنطق الخاص بك في الطريقة ، ولكنها ستقوم بتنظيف بيان if الخاص بك.


Answer #10

مستقلة عن ما تحاول تحقيقه ، هذا

if(a.equals("x") || a.equals("y") || a.equals("z") || Any number of terms...... )
    //Do something

هو دائما فوضوي وغير نظيف. في المقام الأول ، لا يمكن فهمها بسرعة.

إن أبسط حل بالنسبة لي هو التعبير عن نواياك بدلاً من التعبير عنها.

حاول القيام بذلك بدلاً من ذلك:

   public class SomeClass{
    public void SomeMethod(){
        if ( matchesSignificantChar(a) ){
          //doSomething
        }    
    }
    private bool matchesSignificantChar(String s){
        return (s.equals("x") || s.equals("y") || s.equals("z") || Any number of terms......    )
      }
   }

هذا يبسط نطاق البيان الشرطي الخاص بك ويجعل من السهل فهمه أثناء نقل التعقيد إلى نطاق أصغر وأسمه ، يرأسه هدفك.

ومع ذلك ، هذا لا يزال غير قابل للتوسعة. إذا حاولت جعله أكثر نظافة ، يمكنك استخراج الأسلوب المنطقي إلى فئة أخرى وتمريره كمفوض إلى SomeClass'es Constructor أو حتى SomeMethod. كما يمكنك النظر في نمط الإستراتيجية لمزيد من الزيادة.

ضع في اعتبارك أنه كمبرمج سوف تقضي وقتًا أطول في قراءة الشفرة (ليس فقط لك) بدلاً من كتابتها ، لذلك فإن إنشاء رمز أفضل يمكن فهمه سيؤتي ثماره على المدى الطويل.


Answer #11

يمكنك استخدام Arrays.asList() . هذا هو الأسلوب أبسط وأقل verbosity.

Arrays.asList("x","y","z"...).contains(a)

لأسباب تتعلق بالأداء ، إذا كانت مجموعتك كبيرة جدًا ، فيمكنك وضع البيانات في سبب HashSet بالبحث في الوقت الثابت.

على سبيل المثال جعل طريقة استخدام الخاصة بك

public final class Utils{

    private Utils(){}//don't let instantiate

    public static <T> boolean contains(T a,T ... x){
      return new HashSet<>(Arrays.asList(x)).contains(a);
    }
}    

ثم في رمز العميل الخاص بك:

if(Utils.contains(a,"x","y","z","n")){
  //execute some code
}

Answer #12
Set<String> stuff = new HashSet<String>();
stuff.add("x");
stuff.add("y");
stuff.add("z");
if(stuff.contains(a)) {
    //stuff
}

إذا كانت هذه حلقة ضيقة يمكنك استخدام مجموعة ثابتة.

static Set<String> stuff;
static {
    stuff = new HashSet<String>();
    stuff.add("x");
    stuff.add("y");
    stuff.add("z");
}

//Somewhere else in the cosmos

if(stuff.contains(a)) {
    //stuff
}

وإذا كنت تريد أن تكون على يقين من أن أي شيء يتم تعديله بينما لا تبحث.

Set<String> test = Collections.unmodifiableSet(new HashSet<String>() {
        {
            add("x");
            add("y");
            add("z");
        }
    });

إذا كنت ترغب فقط في الحصول على بعض المنطق بحثًا عن حفنة من الشروط المشفرة ، فيمكن أن يكون أحد التبديل أو ما إذا كان بيان الحلول الجديدة أفضل. ولكن إذا كان لديك الكثير من الشروط ، فقد يكون من الجيد فصل التكوين الخاص بك عن المنطق.





if-statement