Шпаргалка по Java

Необходимо явно объявлять все переменные

int a = 2; // целое число
double b = 3.1; // действительное число
String text = "строка текста";

Тип переменной указывать не обязательно, если вы сразу присваиваете значение переменной. Для этого вместо типа можно просто писать var. То есть альтернативно можно писать так:

var a = 2; // целое число
var b = 3.0; // действительное число
var text = "строка текста";

В большинстве случаев достаточно использования var.

Арифметические операции

int a, b, c;
double result;

a = 3;
b = 2;
c = 1;

result = a + b; // в result окажется 5
result = a - b; // в result окажется 1
result = a * b; // в result окажется 6
result = a / b; // деление, так как обе переменные целые, то и результате получаем деление нацело, в result окажется 1
result = (float) a / b; // деление, в result окажется 1.5
result = a % b; // остаток от деления, в result окажется 1

result += 2.5; // увеличить значение result на 2.5
result -= 2.5; // уменшить значение result на 2.5
result *= 2.5; // умножить значение result на 2.5
result /= 2.5; // разделить значение result на 2.5

result++; // инкремент, увеличить значение result на 1
result--; // декремент, уменшить значение result на 1

Операции сравнения

int a = 1, b = 2, c = 3;
Boolean result; // булева (или логическая) переменная

result = a < b; // в result окажется true
result = b > c; // в result окажется false
result = b >= c; // в result окажется false
result = b <= c; // в result окажется true
result = c == b; // сравнение на равенство (обязательно ДВОЙНОЙ знак равенства), в result окажется false
result = c != b; // сравнение на НЕравенство, в result окажется true

Логические операции

int a = 1, b = 2, c = 3;
Boolean result;

// конъюнкция, логическое И
result = a < b && b < c; // проверка что число b лежит между a и с, в result окажется true

// дизъюнкция, логическое ИЛИ
result = a < b || c < a; // проверка что число a лежит вне промежутка b и с, в result окажется true

Контроль исполнения через if

Контроль исполнения завязан на логические значения, которые имеют булевы значения true/false

Формально имеет следующий вид:

if (condition) { // условие
    // выполнится только если condition ИСТИННО (true)
}

Например:

int a = 1, b = 2, c = 3;
if (a < b) {
    System.out.println("a меньше b");
}

Можно добавить блок else на случай если condition окажется ложно

if (condition) { // условие
    // выполнится только если condition ИСТИННО (true)
} else {
    // выполнится только если condition ЛОЖНО (false)
}

Например:

int a = 1, b = 2, c = 3;
if (a > b) {
    System.out.println("a больше b");
} else {
    System.out.println("a не больше b"); // выполнится только этот блок
}

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


if (condition_1) { // условие 1
    // выполнится только если condition_1 ИСТИННО (true)
} else if (condition_2) { // условие 2
    // выполнится только если condition_1 ЛОЖНО (false), а condition_2 ИСТИННО (true)
} else {
    // выполнится только если condition_1 и condition_2 ЛОЖНО (false)
}

Например:

int a = 2, b = 2;

if (a > b) {
    System.out.println("a больше b");
} else if (a == b) {
    System.out.println("a равно b");  // выполнится только этот блок
} else if (a >= b) {
    // хотя это условие формально верно, но выполняться данный блок не будет,
    // так как проверка на равенство a и b идет раньше
    System.out.println("a не меньше b"); 
} else {
    System.out.println("a меньше b");
}

Контроль исполнения через switch

Позволяет проверять переменную или выражение на равенство некоторому дискретному значению и в зависимости от этого значения выполнять тот или иной блок конструкции switch. Допустим мы хотим проверить по оценке в зачетке будет ли студент получать стипендию. Если оценка 4 или 5 - то стипендия будет, а вот если оценка 2 или 3 то придется сидеть на хлебе с водой. Используя if это можно было бы написать так:

var mark = 5;

if (mark == 2 || mark == 3) {
    System.out.println("Стипендии не будет.");
} else if (mark == 4) {
    System.out.println("Ура! Стипендия будет.");
} else if (mark == 5) {
    System.out.println("Гуляем по полной!");
} else {
    System.out.println("Неверное значение оценки...");
}

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

var mark = 5;

switch(mark) {
    case 2:
    case 3:
        System.out.println("Стипендии не будет.");
        break;
    case 4:
        System.out.println("Ура! Стипендия будет.");
        break;
    case 5:
        System.out.println("Гуляем по полной!");
        break;
    default:
        System.out.println("Неверное значение оценки...");
}

Отдельное внимание стоит обратить на наличие ключевого слова break, которое сигнализирует о том что из конструкции switch надо выйти.

Массивы

Массив это упорядоченный список значений. Массив может быть одномерным, многомерным (например, матрица) или массивом массивов. Количество измерений и длина каждого из измерений задаются, когда создается экземпляр массива. Массивы индексируются от нуля: массив с n элементами индексируется от 0 до n-1.

Пример объявления одномерного массива:
var array1D = new int[] { 12, 82, 35, 54 };

System.out.println(array1D[0]); // выводим на экран 12
System.out.println(array1D[1]); // выводим на экран 82
System.out.println(array1D[2]); // выводим на экран 35
System.out.println(array1D[3]); // выводим на экран 54

array1D[1] = 15; // изменили значение элемента массива
System.out.println(array1D[1]); // выводим на экран 15

int result;
result = array1D[0] + array1D[3]; // в result окажется 66

иногда хочется объявить массив безе инициализации его значений, в этом случае необходимо указать его размерность:

var array1D = new int[4]; // объявили массив из 4 элементов, массивы целого типа по умолчанию инициализируются нулями

// В этом случае, каждый элемент массива имеет пустое значение (так называемый 0)
System.out.println(array1D[0]); // выводим на экран 0
System.out.println(array1D[1]); // выводим на экран 0
System.out.println(array1D[2]); // выводим на экран 0
System.out.println(array1D[3]); // выводим на экран 0
Пример объявления двумерного массива:
int[][] array2D = new int[][] { { 1, 2 }, { 3, 4 }, { 5, 6 }, { 7, 8 } };

System.out.println(array2D[2][1]); // выводим на экран 6

array2D[2][1] = 15; // меняем значение элемента
System.out.println(array2D[2][1]); // выводим на экран 15

аналогично можно инициализировать пустой n-мерный массив:

int[][] array2D = new int[4][2]; // инициализируем матрицу 4 на 2

System.out.println(array2D[2][1]); // выводим на экран 0

Списки

Бывают ситуации когда необходимо создать массив количество элементов в котором может меняться, для этих случаев Java предоставляет нам в пользование класс List (то бишь список по-русски). Работа с ним почти ни чем не отличается от работы с массивом, за исключением момента инициализации:

package com.company;

import java.util.ArrayList; // добавляем класс: динамический список

public class Main {
    public static void main(String[] args) {
        // создаем список
        var list = new ArrayList<Integer>();
        // добавляем 4 элемента
        list.add(12);
        list.add(82);
        list.add(35);
        list.add(54);

        System.out.println(list.get(1)); // выводим на экран 82

        list.set(1, 15); // меняем значение элемента
        System.out.println(list.get(1)); // выводим на экран 15

        list.add(20); // добавляем новый элемент, теперь в списке находится {12, 15, 35, 54, 20}
        System.out.println(list.get(4)); // выводим на экран 20

        list.remove(1); // удаляем элемент на позиции 1
        System.out.println(list.toString()); // выведет [12, 35, 54, 20]
    }
}

Циклы

И вот рассмотрев работу с массивами сразу появляется желание найти способ перебрать элементы каким-нибудь более оптимизированным способом. Возьмем пример выше:

int[] array1D = new int[] {12, 82, 35, 54 };

System.out.println(array1D[0]); // выводим на экран 12
System.out.println(array1D[1]); // выводим на экран 82
System.out.println(array1D[2]); // выводим на экран 35
System.out.println(array1D[3]); // выводим на экран 54

Очевидно что писать System.out.println по четыре раза дело неблагородное, мы можем просто создать цикл и запустить функцию System.out.println четыре раза, выглядеть это будет так:

int[] array1D = new int[] {12, 82, 35, 54 };

for (int i = 0; i < 4; i++) { // пробегая счетчиком с нуля до 4 (не включительно)
    // выводим на экран информацию об i-ом элементе
    System.out.println(array1D[i]);
}

тут мы в явном виде указываем количество итераций в цикле, а что если нам не известно количество элементов в массиве (например, мы со списком работаем) или нам просто лень вспоминать, более грамотно запросить количество элементов у самого массива, делается это так:

int[] array1D = new int[] {12, 82, 35, 54 };

for (int i = 0; i < array1D.length; i++) { // пробегая счетчиком с нуля до количества элементов в массиве (не включительно)
    // выводим на экран информацию об i-ом элементе
    System.out.println(array1D[i]);
}

есть еще один способ перебора всех элементов массива, с использованием сокращеного цикла for, которая просто последовательно позволяет получить доступ к каждому элементу массива, причем использование счетчика i в этом случае не нужно:

int[] array1D = new int[] {12, 82, 35, 54 };

for (var element : array1D) {
    System.out.println(element);
}

Контроль управления в цикле с помощью break и continue

бывают ситуации когда перебор элементов хочется прервать, или например пропустить выполнение итерации в цикле. Для этого существует два ключевых слова break и continue

Допустим, что мы хотим выйти из цикла как только встретим первое нечетное число, сделать это можно следующим образом

int[] array1D = new int[] {12, 82, 35, 54 };

for (var element : array1D) {
    if (element % 2 == 1) { // если остаток от деления на 2 равен 1, то число нечетное, а мы переходим внутрь этого if
        break; // выйти из цикла -----.
    }          //                      |
               //                      |
    System.out.println(element); //    |
}                                //    V 

В результат выполнения этого кода, на экран выведется только два значения:

12
82

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

int[] array1D = new int[] {12, 82, 35, 54 };

for (var element : array1D)  { // <-----------------------------------------+                               
                               //                                           |  
    if (element % 2 == 1) {    //                                           |
        continue; // пропускаем итерацию и переходим к следущему элементу __^
    }

    System.out.println(element);
}

В результат выполнения этого кода, на экран выведутся только четные числа:

12
82
54

Конструкции while и do/while

Есть еще два специфических способа построения циклов, использование которых в подавляющем случае излишне. Применяются они как правило, когда количество итераций заранее не известно, и выход их них завязан на выполнение некоторого условия.

Формально конструкция имеет следующий вид:


while(condition) {
    // пока condition имеет значение true, выполнение этого блока будет повторятся
}

Допустим мы хотим поиграть с компьютером в угадайку. Мы загадываем число от 0 до 100, помещаем его в переменную, назовем ее number и хотим посчитать сколько попыток потребуется компьютеру чтобы угадать число. Для имитации процесса угадывания, мы воспользуемся генератором случайных чисел:

import java.util.concurrent.ThreadLocalRandom; // для генерации случайных чисел

public class Main {
    public static void main(String[] args) {
        var ourNumber = 14; // тут число которое мы загадали
        var counter = 1; // счетчик попыток угадывания

        // пока результат очередного случайного числа не совпадет с нашим числом
        while (ThreadLocalRandom.current().nextInt(101) != ourNumber) {
            counter++; // увеличиваем счетчик
        }
        
        // вместо %s будет подставлени
        System.out.printf("Компьютеру потребовалось %s попыток, чтобы угадать наше число.", counter);
    }
}

Теперь запуская программу каждый новый раз, на экран будет выводится разный ответ.

Еще есть конструкция do/while, которая отличается от while тем что она гарантирует выполнение цикла хотя бы один раз


do
{
    // пока condition имеет значение true, выполнение этого блока будет повторятся
    // причем даже если condition имеет значение false, этот блок все равно будет выполнен один раз
} 
while (condition) 

Пример выше можно переписать:

var ourNumber = 14;
var counter = 0; // так как используем do/while счетчик начинаем с 0

do {
    counter++;
} while (ThreadLocalRandom.current().nextInt(0, 101) != ourNumber);

System.out.printf("Компьютеру потребовалось %s попыток, чтобы угадать наше число.", counter);

Обработка данных от пользователя

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

Простой ввод, преобразование строки в число

Допустим мы хотим запросить два числа от пользователя и сложить их, для этого можно было бы написать:

import java.util.Scanner; // подключаем сканер для работы с вводом

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);  // создаем сканер
        var number1 = in.nextInt();
        var number2 = in.nextInt();

        System.out.println(number1 + number2);
    }
}

Imgur

Ввод произвольного количества аргументов

Допустим мы хотим запросить у пользователя n-ое количество чисел, и хотим вывести их сумму, для этого нам пригодится цикл do/while, который как раз позволяет выполнять инструкции в цикле неопределённое количество раз в зависимости от условия. В качестве условия выхода из цикла будет считать ситуацию, когда пользователь не ввел никакого числа (то есть просто нажал enter). Введенные числа мы будем заносить в список. И так у нас получится:

var scanner = new Scanner(System.in);

String inputNumber; // сюда будем фиксировать введенную строку
var numbers = new ArrayList<Integer>(); // сюда будем заносить числа

while (true) { // цикл бесконечный
    inputNumber = scanner.nextLine(); // забираем данные от пользователя
    if (inputNumber.equals("")) {  // если пользователь ничего не ввел то выходим
        break;
    }
    numbers.add(Integer.parseInt(inputNumber)); // добавляем число в список
}

int sum = 0;
for (var value : numbers) {
    sum += value;
}

System.out.printf("Сумма равна: %s", sum); // выводим сумму чисел на экран

получим что-то в этом роде:

Математически функции

Для доступа к математическим функциям, таким как синус, косинус, возведение в степень и другим, используется класс Math, вот пример некоторых наиболее часто используемых функций

System.out.println(Math.cos(Math.PI)); // косинус пи, выведет -1.0
System.out.println(Math.sin(Math.PI / 2)); // синус 90 градусов, выведет 1.0

System.out.println(Math.log10(100)); // логарифм от 100 по основанию 10, выведет 2.0
System.out.println(Math.pow(10, 5)); // возведение 10 в степень 5, выведет 100000.0
System.out.println(Math.sqrt(144)); // корень квадратный из 144, выведет 12.0
System.out.println(Math.abs(-15)); // модуль от -15, выдаст 15

обратите внимание на Math.PI которая является не функцией, а константой, содержащей значение числа \(\pi\)