Подтвердить что ты не робот

Краткая форма для Java Если инструкция Else

У меня есть метод, который проверяет наличие нулей. Есть ли способ уменьшить количество строк в методе? В настоящее время код выглядит "грязным":

private int similarityCount (String one, String two) {

    if (one == null && two == null) {
        return 1;
    } else if (one == null && two != null) {
        return 2;
    } else if (one != null && two == null) {
        return 3;
    } else {
        if(isMatch(one, two))
             return 4;
        return 5;
    }

}
4b9b3361

Ответ 1

private int similarityCount (String one, String two) {

    if (one == null && two == null) {
        return 1;
    } 

    if (one == null) {
        return 2;
    } 

    if (two == null) {
        return 3;
    } 

    if (isMatch(one, two)) {
        return 4;
    }
    return 5;
}

Ответ 2

Я предпочитаю вложенные условия в таких случаях:

private int similarityCount (String one, String two) {
    if (one==null) {
        if (two==null) {
            return 1;
        } else {
            return 2;
        }
    } else {
        if (two==null) {
            return 3;
        } else {
            return isMatch(one, two) ? 4 : 5;
        }
    }
}

Конечно, вы можете получить более короткую версию, используя более тернарные условные операторы.

private int similarityCount (String one, String two) {  
    if (one==null) {
        return (two==null) ? 1 : 2;
    } else {
        return (two==null) ? 3 : isMatch(one, two) ? 4 : 5;
    }
}

Или даже (теперь это становится менее читаемым):

private int similarityCount (String one, String two) {  
    return (one==null) ? ((two==null) ? 1 : 2) : ((two==null) ? 3 : isMatch(one, two) ? 4 : 5);
}

Ответ 3

Поскольку фактическая цель функции состоит в том, чтобы обрабатывать объекты null, сопоставляя их, Id обрабатывает все теги null в инструкции охраны в начале.

Затем, как только вы установили, что никакой аргумент null, вы можете обрабатывать фактическую логику:

private int similarityCount(String a, String b) {
    if (a == null || b == null) {
        return a == b ? 1 : a == null ? 2 : 3;
    }

    return isMatch(a, b) ? 4 : 5;
}

Это более краткий и читаемый, чем другие.

Тем не менее, реальные функции обычно не возвращают такие числовые коды. Если ваш метод не был упрощен, чтобы продемонстрировать проблему, Id настоятельно призывает вас пересмотреть логику и вместо этого написать что-то похожее на следующее:

private boolean similarityCount(String a, String b) {
    if (a == null || b == null) {
        throw new NullPointerException();
    }

    return isMatch(a, b);
}

Или:

private boolean similarityCount(String a, String b) {
    if (a == null) {
        throw new IllegalArgumentException("a");
    }
    if (b == null) {
        throw new IllegalArgumentException("b");
    }

    return isMatch(a, b);
}

Эти подходы были бы более условными. С другой стороны, они могут вызвать исключение. Мы можем избежать этого, возвращая java.util.Optional<Boolean> в Java 8:

private Optional<Boolean> similarityCount(String a, String b) {
    if (a == null || b == null) {
        return Optional.empty();
    }

    return Optional.of(isMatch(a, b));
}

На первый взгляд это может показаться не лучшим, чем возврат null, но опции на самом деле намного превосходят.

Ответ 4

Код выглядит достаточно ясным для меня. Вы можете сократить его с помощью вложенных и тройных операторов:

if(one==null) {
    return two==null ? 1 : 2;
}
if(two==null) {
    return 3;
} 
return isMatch(one,two) ? 4 : 5;

Ответ 5

Это можно сделать в одной строке с использованием условного оператора Java:

return (one==null?(two==null?1:2):(two==null?3:(isMatch(one,two)?4:5)));

Ответ 6

Вы можете создать псевдо-поисковую таблицу. Некоторые люди нахмурились на вложенных тернарных операторах и сильно зависят от пробелов для удобочитаемости, но это может быть очень читаемый подход к условному возврату:

private int similarityCount (String one, String two) {
    return (one == null && two == null) ? 1
         : (one == null && two != null) ? 2
         : (one != null && two == null) ? 3
         : isMatch(one, two)            ? 4
         :                                5;
}

Ответ 7

Мне нравятся выражения.

private static int similarityCount (String one, String two) {    
    return one == null ? 
        similarityCountByTwoOnly(two) : 
        two == null ? 3 : (isMatch(one, two) ? 4 : 5)
    ;
}

private static int similarityCountByTwoOnly(String two) {
    return two == null ? 1 : 2;
}

В стороне, я бы, вероятно, бросил вызов, почему вы это делаете. Я бы предположил, что вы проведете какое-то подтверждение по возвращаемому целому числу после того, как вы его оценили и разделите свою логику на основе этого. Если это так, вы просто сделали менее читаемый чек для null, где пользователь вашего метода должен понимать контракт, неявный в значении целого числа.

Кроме того, здесь простое решение, когда вам нужно проверить, равны ли строки, когда они могут быть null:

boolean same = one == null ? two == null : one.equals(two);

Ответ 8

Избавление от операторов IF - хорошая забава. Использование карты - один из способов сделать это. Он не подходит для этого случая именно из-за вызова isMatch, но я предлагаю его в качестве альтернативы, который обрезает тело метода подобияCount на одну строку с одним IF

Следующий код имеет два IF. Если GetOrDefault не оценил второй аргумент, его можно было бы свести к единице. К сожалению, это делает так, что нулевая проверка внутри isMatch необходима.

Вы могли бы пойти намного дальше, если хотите. Например, isMatch может возвращать 4 или 5, а не логическое, что поможет вам упростить дальнейшее.

import com.google.common.collect.ImmutableMap;
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;

import java.util.Map;

public class SimilarityCount {

    private Map<SimilarityCountKey, Integer> rtn = ImmutableMap.of(new SimilarityCountKey(null, null), 1, new SimilarityCountKey(null, ""), 2, new SimilarityCountKey("", null), 3);

    public int similarityCount(String one, String two) {
        return rtn.getOrDefault(new SimilarityCountKey(one, two), isMatch(one, two) ? 4 : 5);
    }

    private boolean isMatch(String one, String two) {
        if (one == null || two == null) {
            return false;
        }
        return one.equals(two);
    }

    private class SimilarityCountKey {
        private final boolean one;
        private final boolean two;

        public SimilarityCountKey(String one, String two) {
            this.one = one == null;
            this.two = two == null;
        }

        @Override
        public boolean equals(Object obj) {
            return EqualsBuilder.reflectionEquals(this, obj);
        }

        @Override
        public int hashCode() {
            return HashCodeBuilder.reflectionHashCode(this);
        }
    }
}

В случае, если кто-то еще захочет создать трещины в другом решении, вот несколько тестов, которые помогут вам начать работу

 import org.junit.Assert;
import org.junit.Test;

import static org.hamcrest.CoreMatchers.is;

public class SimilarityCountTest {

    @Test
    public void one(){
        Assert.assertThat(new SimilarityCount().similarityCount(null,null), is(1));
    }

    @Test
    public void two(){
        Assert.assertThat(new SimilarityCount().similarityCount(null,""), is(2));
    }

    @Test
    public void three(){
        Assert.assertThat(new SimilarityCount().similarityCount("",null), is(3));
    }

    @Test
    public void four(){
        Assert.assertThat(new SimilarityCount().similarityCount("",""), is(4));
    }

    @Test
    public void five(){
        Assert.assertThat(new SimilarityCount().similarityCount("a","b"), is(5));
    }

}

Ответ 9

Это должно быть немного быстрее, если ни один из них не равен null, поскольку в этом случае он выполняет только один оператор if.

private int similarityCount (String one, String two) {

    if (one == null || two == null) {  // Something is null
        if (two != null) { // Only one is null
            return 2;
        }

        if (one != null) { // Only two is null
            return 3;
        }

        return 1; // Both must be null
    } 

    return isMatch(one, two) ? 4 : 5;
}

Ответ 10

LOL... Программирование не является конкурсом красоты. Ваши коды

if (one == null && two == null) {
        return 1;
} else if (one == null && two != null) {
        return 2;
    } else if (one != null && two == null) {
        return 3;
    } else {
        if(isMatch(one, two))
             return 4;
        return 5;
    }

НЕ грязные, но достаточно красивые для мирян и экспертов. Что вы думаете о следующем кодировании

return one == null && two == null ? 1:
       one == null && two != null ? 2:
       one != null && two == null ? 3:
       isMatch(one, two) ? 4 : 5;

Отлично, не так ли? Ну, для мирян это "вуду", для "экспертов"... не стоит обсуждать "вкус", "политика" и "религия". НО с точки зрения производительности это так:

  • 1-я версия быстрее
  • вторая версия неуклюже (или медленнее)

WHY`? Просто скомпилируйте его "javac -g: none Test5 *.java" и сравните сгенерированные байт-коды. Я сделал это и вот результаты:

Первая версия:

public class Test5 {
    public static void main(String[] args) {
        String one = "1";
        String two = "2";
        System.out.println(check(one, two));
    }
    private static int check(String one, String two) {
        if (one == null && two == null) {
                return 1;
        } else if (one == null && two != null) {
                return 2;
            } else if (one != null && two == null) {
                return 3;
            } else {
                if(isMatch(one, two))
                     return 4;
                return 5;
            }
    }
    public static boolean isMatch(String a, String b) {
        return true;
    }
}

создано 570 байт

Вторая версия:

public class Test5a {
    public static void main(String[] args) {
        String one = "1";
        String two = "2";
        System.out.println(check(one, two));
    }
    private static int check(String one, String two) {
        return one == null && two == null ? 1:
               one == null && two != null ? 2:
               one != null && two == null ? 3:
               isMatch(one, two) ? 4 : 5;
    }
    public static boolean isMatch(String a, String b) {
        return true;
    }
}

создает 581 байт

Ясно, что нужно обрабатывать 11 байтов, и это требует времени... чем больше "лишних" кодов имеет приложение, тем хуже производительность.