Значение null

Все объектные типы (пока только String) могут иметь значение null:

String s = null;

null означает “отсутствие значения”

String t = "";

s - значения нет, т.е. в s не хранится никакая строка. t - в ней хранится пустая строка, т.е. строка без символов (длины 0)

System.out.println(null)
System.out.println(s) в обоих случаях выведется текст null, `println` так устроен, что для `null` выводит текст null Но в общем случае никаких операций с null совершать нельзя, это ошибка. `s.length()` - ошибка, примерно как деление на 0 `s.startsWith("abc")` - такая же ошибка. (если ошибка случится, вы увидете сообщение в консоли `NullPointerException`).

Не считая println, с null можно делать фактически только одну вещь: сравнивать с null if (s == null) <- нормально. if (s != null) в println примерно написано так: if (s == null) println("null") else println(s)

Кстати, s.equals(null) - будет ошибка, если s == null

Итак, null нужно пользоваться аккуратно. При возможности его нужно избегать. Сейчас даже принято избегать его всеми возможными способами. Большинство возникающих ошибок в существующих Java программах - это как раз NullPointerException.

Циклы в Java

Цикл while

Оформление

while (выражение типа boolean) {
    тело цикла с отступом 4 пробела (как всегда)
}

если тело состоит из одного оператора, фигурные скобки можно не писать

Работа цикла. Проверяется условие, если оно true, выполняется тело цикла. После чего снова проверяется условие и т.д. А если условие ложно, цикл заканчивается.

Примеры:

int i = 0;
while (i < 10) {
    sout(i);
    i = i + 1; // i += 1 или i++ или ++i
}

что выведет цикл: 0 1 2 … 9

Цикл while может не выполниться ни разу. Это бывает, если условие сразу false

У цикла while есть двойник: цикл

do {
    тело цикла с отступом 4 пробела
} while (условие);

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

Операторы break и continue

Оператор break совершает выход из цикла Оператор continue завершает текущую операцию и переходит к условию:

int i = 0;
while (i < 10) {
    sout(i);
    if (i == 3)
        break;
    sout("hello");
    i += 1;
} Что будет выведено:

0
hello
1
hello
2
hello
3

Представим, что вместо break написано continue.

0
hello
1
hello
2
hello
3
3
3
3
3
и т.д. до бесконечности

Шаблон использования цикла while: Обычно он нужен, когда заранее не известно количество итераций. Т.е. мы повторяем действие, пока не выполнится условие. while проверяет условие в начале. do while - в конце. А если хочется проверять условие в середине, то надо так:

while (true) { //бесконечный цикл, повторяй постоянно
    String s = прочитай команду с клавиатуры
    if (s.equals("stop"))
        break; //выходим, если пользователь просит остановиться
    sout("Вы ввели " + s);
}

Цикл for

1) сложнее, чем в Pascal 2) но рекомендуется им пользоваться только для простых переборов, как в Pascal

for (инициализатор; условие; итератор) {
    тело цикла с отступом 4 пробела
}

как всегда, если тело из одного оператора, {} можно не писать.

алгоритм действия:

  1. инициализатор, обычно в нем заводятся переменные, которые видны только внутри цикла.
  2. Проверяется условие, если оно false - завершить цикл
  3. выполнить тело
  4. выполнить итератор. Здесь обычно меняются переменные цикла
  5. Переход к шагу 2

Классический шаблонный цикл for:

for (int i = 0; i < 10; i++)
    sout("i = " + i);

Выведет

i = 0
i = 1
i = 2
...
i = 9

Если внутри цикла не менять переменную цикла, то условие всегда верно. В нашем случае, всегда верно, что i < 10

Другие шаблоны

for (int i = 0; i <= 10; i++) перебор от 0 до 10 включительно
for (int i = 10; i >= 1; i--) перебор от 10 до 1 включительно

пример нешаблонного for

for (int i = 0, j = 10; i < j; i++, j--)
    sout(i + ", " + j);

выведет:

0, 10
1, 9
2, 8
3, 7
4, 6

5, 5 - не выведет, т.к. условие i < j будет неверно.

Массивы

Массив - упорядоченный набор элементов какого-то определенного типа. Если к типу приписать в конце [], то получится массив элементов этого типа. Например, int[] - массив целых чисел char[] - массив символов String[] - массив строчек Все массивы в Java - одномерные. (если нужны матрицы и другие многомерные массивы - делайте массив, состоящий из массивов - в следующий раз)

Создание массива.

  1. new тип[сколько] например, new int[10] - массив из 10 чисел. new String[2] - массив из двух строчек

    int[] a = new int[10]; //переменная a хранит 10 int String[] s = new String[2]; //s хранит 2 строки.

    Из каких элементов состоят создаваемые таким образом массивы? Из 0 (для чисел), из ‘\0’ (символ с кодом 0) для char, из false (для boolean). Из null для String.

  2. new тип[]{значения через ,}

    new int[]{10, 20, 30} - массив из трех элементов 10, 20, 30} new String[]{“понедельник”, “вторник”, …}

    String[] week = new String[]{“понедельник”, “вторник”, …};

  3. Если вы пользуетесь вторым способом создания массивов в инициализаторе переменной, то можно писать короче:

String[] week = {“понедельник”, “вторник”, …};

(т.е. можно не писать new String[]) Но!! это работает только при инициализации, т.е. вот так нельзя:

week = {“понедельник”, “вторник”, …};

Обращение к элементам массива:

массив[индекс] все индексы начинаются с нуля.

int[] a = new int[]{10, 20, 30};
sout(a[1]); //печатает 20
a[1] = 42; //теперь массив a это 10, 42, 30

а если написать a[3], или a[-1], то произойдет ошибка во время выполнения программы. В ошибке будет сказано ArrayIndexOutOfBoundsException: 3 (или -1) т.е. в ошибке указывается, какой именно индекс был неверный.

Перебор элементов массива.

Чаще всего для работы с массивом нужен цикл. Шаблонный цикл for:

int[] a = {10, 20, 30};
//a.length - длина массива, в данном случае 3.
//!! а длина строки считается s.length()
for (int i = 0; i < a.length; i++)
    sout(a[i]); //действие с очередным элементом.

i должно быть меньше длины массива. Например, если в массиве 3 элемента, то перебирать надо индексы 0, 1, 2.

В обратную сторону перебор элементов массива

for (int i = a.length - 1; i >= 0; i--)
    sout(a[i]);

В подавляющем большинстве случаев вам нужно перебирать массив от начала до конца, и вам не нужен индекс элемента массива. Тогда используйте цикл “for each”

for (заводится переменная : массив)
  действие с переменной

for (int x : a)
    sout(x);

переменной x последовательно присваются элементы массива, т.е. сначала x = 10, потом x = 20, потом x = 30. Индекс 0, 1, 2 нам не доступен.

Еще пример

for (String day : new String[]{"понедельник", "вторник", ...})
    sout(day);

Если можно написать for each, пишите for each, а не обычный for.