круговой перебор элементов массива
Как можно реализовать переключение элементов массива (например каналов телевизора) по кругу? Например при вызове метода nextChannel() с "D" переключиться на "A".
public class Tv{
int currentChannel = 1;
int maxChannel = 5;
int step = 1;
List<String> channels = new ArrayList<>(Arrays.asList("A", "B", "C", "D"));
public String nextChannel() {
currentChannel += step;
return String.format("Канал: %s - %s\n", currentChannel, channels.get(currentChannel));
}
Я пытался сделать следующее, но выбрасывается исключение indexOutOfBounds.
public String nextChannel() {
currentChannel += step;
if(currentChannel > channels.size()){
currentChannel = 0;
currentChannel += step;
}
return String.format("Канал: %s - %s\n", currentChannel, channels.get(currentChannel));
}
}
Ответы (3 шт):
Мне кажется итератор в данном случае подходит лучше. К тому же это не просто итератор, это листитератор, следовательно, можно двигаться не только к следующему каналу, но и к предыдущему:
import java.util.List;
import java.util.ListIterator;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class Tv {
private final List<String> channels;
private ListIterator<String> iterator;
public Tv(String ... channels) {
this.channels = Stream.of(channels).collect(Collectors.toList());
this.iterator = this.channels.listIterator();
}
public String nextChannel() {
if (iterator.hasNext()) return iterator.next();
else {
iterator = channels.listIterator();
return iterator.next();
}
}
public static void main(String[] args) {
Tv tv = new Tv("A", "B", "C", "D");
for (int i = 0; i < 10; i++) {
System.out.println("Канал: " + tv.nextChannel());
}
}
}
Если из вашей реализации убрать повторно вкравшееся увеличение на step, то всё должно работать
public String nextChannel() {
currentChannel += step;
if(currentChannel > channels.size()){
currentChannel = 0;
}
return String.format("Канал: %s - %s\n", currentChannel, channels.get(currentChannel));
}
Кроме того, можно использовать остаток от деления. Обратите внимание, что возможен и отрицательный шаг благодаря + channels.size() (не нужен отрицательный - уберите это)
currentChannel = (currentChannel + step + channels.size()) & channels.size();
В сравнении нужно использовать == т.к. нумерация массива начинается с 0, и последний адресуемый элемент имеет индекс size-1. В этом причина исключения
По той же причине инкремент в if действительно лишний
Для удобства пользователя при выводе результата к номеру канала можно прибавлять 1
Ели step всегда равен 1, то можно сократить код за счёт оператора инкремента ++. Результат может выглядеть примерно так:
public class Tv { private int currentChannel = -1; private List<String> channels = Arrays.asList("A", "B", "C", "D");
public String nextChannel() { if (++currentChannel == channels.size()) { currentChannel = 0; } return String.format("Канал: %s - %s\n", currentChannel + 1, channels.get(currentChannel)); } }