Перебрать массив элементов, не зная его размеров
Сашко , спасибо я использовал ваш вопрос , на джаве . И с легка переделал его , на СИ плюс плюс . Вы мне сильно помогли .
11 окт 2016 в 13:35
2 ответа 2
Сортировка: Сброс на вариант по умолчанию
@Сашко, Доброе время суток!
int[] array = new int[] < 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 101, 102, 103, 104 >; for (int i = 0; i
Отслеживать
ответ дан 11 ноя 2013 в 17:22
user14313 user14313
Ооо, работает 🙂 Спасибо, @Ковальский!
11 ноя 2013 в 17:25
Для перебора всех элементов массива в Java есть как минимум три подхода:
Цикл с условием
Это привычный «сишный» способ. Просто проходим все индексы массива, перед каждой итерацией проверяя, не дошли ли до конца.
for (int i = 0; i
Цикл по коллекции
Пишем вначале переменную, которая будет принимать значения элементов массива, а затем через двоеточие — имя нашего массива. Если нужен индекс, его придётся считать отдельно.
int i = 0; for (int element : array)
Применение потоков
Начиная с Java 8 доступен специальный интерфейс Stream. Его удобно использовать вкупе с лябда-функциями.
IntStream.of(array).forEach(element -> System.out.println("см. ==> " + element)); // если функции передаётся просто один аргумент, можно обойтись без стрелки IntStream.of(array).forEach(System.out::println);
Бонус: последние два способа будут работать не только с массивами, а с произвольного вида коллекциями.
Пример для каждого: улучшен цикл для перебора массива Java
Цикл For-Each — это еще одна форма цикла for, используемая для обхода массива. Цикл for-each значительно сокращает код, и в цикле не используется индекс или, скорее, счетчик.
Синтаксис:
Давайте возьмем пример с использованием массива строк, который вы хотите перебрать без использования каких-либо счетчиков.
Рассмотрим массив строк arrData, инициализированный следующим образом:
String[] arrData = ;
Хотя вы, возможно, знаете такие методы, как определение размера массив а затем перебирая каждый элемент массива с использованием традиционного цикла for (счетчик, условие и приращение), нам нужно найти более оптимизированный подход, который не будет использовать такой счетчик.
Это традиционный подход цикла for:
for(int i = 0; i
Вы можете увидеть использование счетчика, а затем использовать его в качестве индекса массива.
Java предоставляет способ использования цикла «for», который будет перебирать каждый элемент массива.
Вот код массива, который мы объявили ранее:
for (String strTemp : arrData)
Вы можете увидеть разницу между петлями. Код значительно сократился. Кроме того, в цикле не используется индекс или, скорее, счетчик.
Убедитесь, что тип данных, объявленный в цикле foreach, соответствует типу данных массив/список что вы повторяете.
Здесь у нас есть весь класс, показывающий приведенное выше объяснение:
class UsingForEach < public static void main(String[] args) < String[] arrData = ; //The conventional approach of using the for loop System.out.println("Using conventional For Loop:"); for(int i=0; i < arrData.length; i++)< System.out.println(arrData[i]); >System.out.println("\nUsing Foreach loop:"); //The optimized method of using the for loop - also called the foreach loop for (String strTemp : arrData) < System.out.println(strTemp); >> >

Ожидаемый результат:
Using conventional For Loop: Alpha Beta Gamma Delta Sigma Using Foreach loop: Alpha Beta Gamma Delta Sigma
- Программа для печати простых чисел от 1 до 100 на Java
- Сортировка выбором в программе Java с примером
- Абстрактный класс и интерфейс в Java – разница между ними
- 100+ вопросов и ответов на собеседовании по Java (2023 г.)
- Учебное пособие по JAVA в формате PDF: основы для начинающих (загрузить сейчас)
Кофе-брейк #112. Как объявить, инициализировать и перебрать массив в Java. Как остановить поток Java без использования Thread.stop()?

Как объявить, инициализировать и перебрать массив в Java

Источник: FreeCodeCamp В этой статье мы поговорим о массивах в Java. Мы рассмотрим несколько примеров, которые помогут понять, что такое массив, как его объявить и как использовать в коде Java.
Что такое массив?
В Java мы используем массив для хранения нескольких значений одного и того же типа данных в одной переменной. Его также можно рассматривать как набор значений одного и того же типа данных. Это означает, что если вы собираетесь хранить строки, например, в своем массиве, то все значения вашего массива должны быть строками.
Как объявить массив в Java
Для объявления массива мы используем квадратные скобки [ ] . Примерно так:
String[] names;
Здесь мы объявили переменную с именем names , которая будет содержать массив строк. Если же нам нужно объявить переменную для integers (целых чисел), то мы сделаем это так:
int[] myIntegers;
Таким образом, чтобы создать массив, мы указываем тип данных, которые будут храниться в массиве, за которыми следуют квадратные скобки, а затем имя массива.
Как инициализировать массив в Java
Инициализировать массив означает присвоить значения массиву. Давайте инициализируем массивы, которые мы объявили в предыдущем разделе:
String[] names = ;
int[] myIntegers = ;
Мы инициализировали наши массивы, передав значения с одним и тем же типом данных, разделив каждое значение запятой. Если бы мы хотели получить доступ к элементам/значениям в нашем массиве, мы бы обратились к их порядковому номеру в массиве. Индекс первого элемента равен 0. Вот пример:
String[] names = ; System.out.println(names[0]); // John System.out.println(names[1]); // Jade System.out.println(names[2]); // Love System.out.println(names[3]); // Allen
Теперь, когда мы знаем, как получить доступ к каждому элементу, давайте изменим значение третьего элемента.
String[] names = ; names[2] = "Victor"; System.out.println(names[2]); // Victor
Мы также можем проверить длину массива, используя свойство length . Вот пример:
String[] names = ; System.out.println(names.length); // 4
Как перебрать массив в Java
Для перебора элементов массива мы можем использовать цикл for .
String[] names = ; for (int i = 0; i < names.length; i++) < System.out.println(names[i]); >// John // Jade // Love // Allen
Цикл выше будет печатать элементы нашего массива. Мы использовали свойство length , чтобы указать, сколько раз цикл должен запускаться.
Заключение
В этой статье мы узнали, как объявлять и инициализировать массивы в Java-коде. Мы также увидели, как получить доступ к каждому элементу массива и как перебрать эти элементы в цикле. Удачного кодирования!
Как остановить поток Java без использования Thread.stop()?

Источник: 4comprehension Если вы это читаете, то вы, вероятно, задаетесь вопросом, почему, и, самое главное, как остановить поток, если нельзя просто полагаться на метод Thread#stop() , который устарел, начиная с Java 1.2? Краткий ответ заключается в том, что следует использовать прерывания (interruptions), потому что Thread#stop небезопасен. Но если вы хотите понять, почему, как и для чего нужно это надоедливое InterruptedException , продолжайте читать.
Проблема с Thread#stop()
Как бы интуитивно это не звучало, но прерывание уже запущенного потока, запуск и остановка — это два совершенно разных случая. Почему? Когда мы запускаем новый поток, мы начинаем с нуля, что является четко определенным состоянием, но когда мы пытаемся остановить существующий поток, это может произойти в середине операции, которую нельзя прерывать немедленно . Представьте поток, вносящий изменения в потокобезопасную структуру данных. Пока он находится в середине критической секции… и вот поток волшебным образом исчезает — блокировки снимаются, и теперь другой поток может наблюдать структуру данных, оставшуюся в несогласованном состоянии. Рассмотрим следующий пример потокобезопасного счетчика (thread-safe counter) с некоторым внутренним состоянием:
class ThreadSafeCounter < private volatile int counter = 0; private volatile boolean dirty = false; public synchronized int incrementAndGet() < if (dirty) < throw new IllegalStateException("this should never happen"); >dirty = true; // . Thread.sleep(5000); // boilerplate not included // . counter = counter + 1; dirty = false; return counter; > >
Как видите, метод getAndIncrement() увеличивает счетчик и изменяет флаг dirty . Блокировки гарантируют, что каждый раз, когда поток входит в getAndIncrement() , флаг dirty устанавливается в false. Теперь давайте создадим поток и резко остановим его:
var threadSafeCounter = new ThreadSafeCounter(); var t1 = new Thread(() -> < while (true) < threadSafeCounter.incrementAndGet(); >>); t1.start(); Thread.sleep(500); t1.stop(); threadSafeCounter.incrementAndGet(); // Exception in thread "main" java.lang.IllegalStateException: this should never happen
Теперь экземпляр threadSafeCounter , несмотря на правильную реализацию, постоянно поврежден из-за резкой остановки потока. Как это исправить?
Совместное прерывание потока (Cooperative Thread Interruption)
- Логический прерванный флаг (boolean interrupted flag)
- InterruptedException
Обработка прерываемого флага
Находясь внутри потока, мы можем проверить, был ли он прерван, вызвав один из методов:
Thread.currentThread().isInterrupted(); // reads the interrupted flag Thread.interrupted(); // reads and resets the interrupted flag
Поскольку не существует универсального способа обработки прерывания, нам нужно применить действие, которое соответствует нашему контексту. В примере из предыдущего раздела поток увеличивает наш счетчик в бесконечном цикле. Вместо немедленной остановки мы могли бы просто подождать, пока поток завершит свою работу по возрастанию, а затем выйти из цикла:
var threadSafeCounter = new ThreadSafeCounter(); var t1 = new Thread(() -> < while (!Thread.interrupted()) < threadSafeCounter.incrementAndGet(); >>); t1.start(); Thread.sleep(500); t1.interrupt(); threadSafeCounter.incrementAndGet();
Теперь поток благополучно завершается в нужный момент, не вызывая хаоса.
Обработка InterruptedException
Что будет, если мы попытаемся прервать ожидающий поток? Естественно, мы не можем учесть флаг interruption , потому что поток занят блокирующей операцией. Вот почему существует InterruptedException . Это не стандартное исключение, а другая форма сигнала прерывания, которая существует исключительно для обработки прерываний блокирующих операций! Подобно Thread#interrupted , он сбрасывает флаг interruption . Давайте снова изменим приведенный выше пример и введем паузы перед каждым приращением. Теперь нам нужно обработать InterruptedException , созданное Thread#sleep :
var threadSafeCounter = new ThreadSafeCounter(); var t1 = new Thread(() -> < while (!Thread.interrupted()) < threadSafeCounter.incrementAndGet(); try < Thread.sleep(10000); >catch (InterruptedException e) < break; >> >); t1.start(); Thread.sleep(500); t1.interrupt(); assertThat(threadSafeCounter.incrementAndGet()).isGreaterThan(0);
В нашем случае достаточно было просто выйти из цикла. Но как быть, если вы не считаете, что конкретный метод должен отвечать за обработку прерываний? что делать, если сигнатура метода не может быть изменена? В таком случае нам нужно восстановить флаг interruption и/или переупаковать исключение, например:
try < Thread.sleep(1000); >catch (InterruptedException e)
try < Thread.sleep(1000); >catch (InterruptedException e)
Заключение:
- Thread#stop не устарел без причины — он действительно очень небезопасен.
- Потоки останавливаются через прерывания (interruptions) — сигналы, интерпретируемые самим потоком.
- InterruptedException — это не обычное исключение — это встроенный в Java способ сигнализации о прерывании потока.
- Thread.currentThread().isInterrupted() и Thread.interrupted() — не одно и то же. Первый просто считывает флаг interruption , а другой сбрасывает его после.
- Универсального способа обработки сигналов прерывания не существует — “это зависит от обстоятельств”.
Перебор массива несколько раз и с заданных элементов
Доброго времени суток. Задали тестовую задачу — Круговой массив — массив из элементов, в котором по достижению конца массива следующим элементом будет снова первый. Mассив задается числом n, то есть представляет собой числа от 1 до n. Напишите программу, которая выводит путь, по которому, двигаясь интервалом длины m по заданному массиву, концом будет являться первый элемент. Началом одного интервала является конец предыдущего. Путь — массив из начальных элементов полученных интервалов.
Пример: n = 5, m = 4
Решение: Круговой массив: 12345. При длине обхода 4 получаем интервалы: 1234, 4512, 2345, 5123, 3451. Полученный путь: 14253.Параметры передаются в качестве аргументов командной строки.
Например, для последнего примера на вход подаются аргументы: 5 4
Ожидаемый вывод в консоль: 14253
1 2 3 4 5 6 7 8 9 10 11 12 13 14
public static void main(String[] args) { int[] circle = new int []{1, 2, 3, 4, 5, 6}; Scanner scan = new Scanner(System.in); System.out.println("Введите количество интервалов"); int m = scan.nextInt(); System.out.println("Введите длину интервалов"); int n = scan.nextInt(); for(int i : circle) { System.out.println(circle[i]); } }
Добавлено через 24 минуты
Уточнение — Ожидаемый вывод в консоль: 14253 это первые числа — при длине обхода 4 получаем интервалы: 1 234, 4 512, 2 345, 5 123, 3 451
