Изменить / увеличить значение условия цикла while внутри метода - хорошо или плохо - - PullRequest
0 голосов
/ 09 сентября 2018

Извините, если подобные вопросы задавались ранее, я не смог найти удовлетворительных ответов при поиске.

Суть вопроса в том, является ли плохой практикой "скрывать" приращения / изменения значения, используемого в качестве условия в цикле while.

int i = 0; // global/class variable

while(i < str.length()) {
    someMethod(i);
}

Где someMethod увеличивает i.

Я сканирую некоторые строки и, основываясь на символах, вызываю разные методы. Метод получает текущий индекс строки в качестве аргумента, читает / обрабатывает некоторые символы, создает объект и возвращает новый текущий индекс.

Пример:

int i = 0;

while(i < str.length()) {
    if(condition(str.charAt(i))) i = someMethod(i, str);
    else if(condition2(str.charAt(i))) i = someOtherMethod(i, str)
    else ...
}

Однако все не так просто. В некоторых случаях метод condition () должен обработать некоторые символы, прежде чем он может завершиться с истиной или ложью. Если это правда, мы уже знаем достаточно, чтобы решить, с каким объектом создать SomeMethod становится более или менее устаревшим. Вместо этого мы можем просто создать объект в условии (), но нам нужно сообщить циклу новое значение i.

Решение состоит в том, чтобы объявить i как переменную global / class и установить правильное значение в условии (). Однако тогда мы «скрываем» изменение значения i.

Возможное решение - использовать сам метод как часть условия.

int i = 0; 
int j = 0;

while(i < str.length()) {
    if(i < (j = someMethod(i, str))) i = j; 
    else if(i < (j = someOtherMethod(i, str))) i = j; 
    else..
}

Если правильная последовательность символов отсутствует, someMethod возвращает i без изменений (i == j и следующее, если выполняются условия). Если правильная последовательность присутствует, someMethod возвращает i + количество символов, которые он использовал (i

Мне не нравится, когда значения "магически" меняются внутри метода, когда он используется в качестве условия в цикле, но я не фанат if (i <(j = someMethod (i, str)) )) или. </p>

Я студент, и я просто хочу узнать ваше мнение о том, как бы вы написали / решили это наиболее читабельным / понятным способом?

1 Ответ

0 голосов
/ 09 сентября 2018

Использование изменяемой глобальной переменной int, вероятно, не является хорошим решением: оно может использоваться в любом месте по ошибке в классе и, таким образом, нарушает фактическую логику.
Способ полагаться на промежуточную локальную переменную делает чтение более сложным по неоправданным причинам.

Так что первый способ присвоения возврата вызова i звучит лучше:

int i = 0;

while(i < str.length()) {
    if(condition(str.charAt(i))) i = someMethod(i, str);
    else if(condition2(str.charAt(i))) i = someOtherMethod(i, str)
    else ...
}

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

Вы также можете использовать AtomicInteger, но это может показаться немного запутанным.

public class Index {

    private int value;

    public void set(int value) {
        this.value = value;
    }

    public int get() {
        return value;
    }    
}

И используйте это:

String str = ...;

for(Index index = new Index(); index.get() < str.length();) {       
    if(condition(str.charAt(index.get())))  someMethod(index, str);
    else if(condition2(str.charAt(index.get()))) someOtherMethod(index, str);
    else ...
}
...