Данная статья перевод второй части статей посвящённых использованию Java на Raspberry Pi. Перевод первая части вызвал большой интерес к возможности применению Java на Raspberry Pi. Оригинал этой статьи был опуликован в 16 номере журнала MagPi.
Это вторая статья об использование Raspberry Pi для программирования на языке Java, прочитав её вы узнает больше о конструкциях этого языка и сможете попробовать написать более сложные программы. Также она может оказаться полезной тем, кто хочет узнать о языке С, так как основной синтаксис Java совпадает с синтаксисом С.
В начале данной статьи я подробнее опишу управляющие конструкции. А дальше я перейду к описанию числовых, строковых и логических типов данных, приведя примеры их использования. С учетом всего этого в наши примеры программ будет добавлена более сложная логика выполнения. Ну что-же, давайте приступать к работе!
Подробнее об управляющих конструкциях
В первой статье вышедшей в MagPi #14 мы познакомились с двумя управляющими конструкциями: if и while. Я знаю, что вы об этом помните, но на всякий случай напоминаю. Блок конструкция if будет выполнен, только в случае, если значение логического выражения в круглых скобках истина. Для примера:
if (a > 3) { c = c + a; }
Складываем a и c только в случае, когда значения a больше 3. Выражение в круглых скобках, называемое состоянием, может принимать значение true(истина) или false(ложь), т.е. тип данных boolean(Подробнее о логическом типе данных ниже по тексту статьи).
Конструкция if может включать в себя блок запускаемый при значении состояния false. Для примера:
if (score > 50) {
System.out.println("You won! :)");
} else {
System.out.println("You lost. :(");
}
Следующая рассмотренная нами конструкция была while. Исполнен блок конструкции while может быть только в случаях, когда состояние выражения в скобках будет равно true, т.е. это может быть один и более раз, а может быть и не разу. Для примера:
int f = 10;
while (f < 20) {
System.out.println(f);
f++;
}
Целые числа от 10 до 19 будут печататься пока переменная f не станет равна 20 и результат выражения изменится на false. Ещё, вы обратили внимание на червёртую строку? Хорошо, если заметили. Два знака плюс после переменной а увеличивают её на 1. Это короткий вид записи:
f = f + 1;
Аналогично:
f--;
Знаки минус уменьшают значение присваиваемое переменной f. Иначе это будет выглядеть так:
f = f - 1;
Теперь разберём конструкцию for. Конструкция for похожа на while, но для неё в одной строке можно сочетать критерии выполнения и выражение изменяющие значение переменной. По этому перебор чисел от 10 до 19 можно записать используя for:
for (int f = 10; f < 20; f++) {
System.out.println(f);
}
Да, данный вариант выглядит компактнее чем пример с while. Однако while, в некоторых случаях, может быть удобнее для выполнения циклов.
Секция в скобках для конструкции for разделена на три части. Первая для инициализации переменной в начале, вторая для проверки переменной при каждом повторе цикла, третья для изменения переменной в конце выполнения каждого цикла.
Теперь откроем ваш редактор и создадим новую программу:
public class Countdown {
public static void main(String[] args)
throws InterruptedException {
for (int t = 10; t >= 0; t--) {
System.out.println("-> " + t);
Thread.sleep(1000);
}
System.out.println("-> Fire!");
}
}
Компиллируем её командой javac и запускаем java(подробнее в предыдущей статье). Эта программа будет отсчитывать 10 секунд после чего напечатает «Fire!». Как программа изменяет переменную t? Двойной минус уменьшает значение t от 10 до 0. Но зачем тогда понадобилась строка Thread.sleep(1000);? Она создаёт в программе задержку в 1 секунду(1000 миллисекунд) на каждом шаге цикла. Используя метод Thread.sleep, вы делаете задержку только в рамках блока for. Сейчас оставим всё как есть, об обработке исключений я расскажу позже.
Усложним задачу #3: Создадим новую программу Countup.java для счёта от 1 до 20 с задержкой в одну секунду. И когда счёт дойдёт до 15 выводим сообщение «Five to go...».
Ну и напоследок ещё раз взглянем на switch. Конструкция switch проверяет значения переменной и в зависимости от того, чему равна переменная в круглых скобках, выполняет код после двоеточия. Пример:
import java.util.Random;
public class CardinalDirection {
public static void main(String[] args) {
Random r = new Random();
int dir = r.nextInt(4);
switch (dir) {
case 0:
System.out.println("North");
break;
case 1:
System.out.println("West");
break;
case 2:
System.out.println("South");
break;
default:
System.out.println("East");
break;
}
}
}
В этом примере целое число генерируется случайно в диапазоне от 0 до 3. Но, что интересно, значение числа не показывается, оно нужно только для указания. Каждый из блоков выполняется только, если совпало значение переменной с значением после case. Заметьте я не стал ставить case для числа 3, использовал конструкцию default. Это хороший пример того, что лучше всегда ставить default, что-бы при любом не совпадающем значении выбирался этот блок команд.
Хорошо, ну вот и всё что я хотел рассказать об управляющих конструкциях. Конечно есть и другие более экзотические конструкции, такие как continue или do-while, но они не так часто используются и я оставлю их вам, на самостоятельное изучение.
Ну, а теперь можно перейти к совершенно другой теме изучения Java.
Пара бит о числах
Рано или поздно вам нужны будут математические расчёты, в этой главе даны основы с чего необходимо будет их начинать изучать. В Java каждая числовая переменная, это один из базовых типов языка. В Java четыре целых типа(без десятичных разрядов), два с плавающей точкой(с десятичными разрядами) и два высокой точности. Для использования в программе вы объявляете переменную один раз, затем по ходу выполнения программы меняете её значения. Для примера:
int trees; // declaration
trees = 17665785; // assignment
Но вы можете сразу объявив переменную присвоить ей значение, для этого две строки объединим в одну:
// declaration & assignment
int trees = 17665785;
Вы заметили //? Две косые черты обозначают начало комментария, всё что идёт после них Java игнорирует. Таким способом вы можете после них оставлять любые свои заметки и напоминания по выполнению программы, что-бы через пару месяцев или даже лет вспомнить, как ваша программа должна работать.
А теперь диапазон доступных значений для четырёх типов целых переменных:
byte: от -128 до 127
short: от -32 768 до 32 767
int: от -2 147 483 648 до 2 147 483 647
long: от -9 223 372 036 854 775 808
до 9 223 372 036 854 775 807
Чаще вам понадобится третий тип(int). Но если вам нужны будут числа с десятичными дробями(с плавающей запятой), в Java есть два типа данных:
float: от ±1,401298e-45 до ±3,402823e+38
double: от ±4,94065645841246e-324
до ±1,79769313486231e+308
Обычно для математических расчетов отдают предпочтение типу double (15 знаков после запятой), чем типу float (7 знаков после запятой).
В Java четыре арифметических оператора +, -, * и /, и ещё круглые скобки для выставления приоритетов вычисления. Ниже расчёты с этими операторами:
public class Numbers {
public static void main(String[] args) {
int x = 5;
System.out.println(7 + x * 3); // 22
System.out.println((7 + x) * 3); // 36
System.out.println(7 / 3); // 2
// 1 (remainder)
System.out.println(16 % 3);
// 2.33333333
System.out.println(7.0 / 3.0);
System.out.println(3.14159265 * x * x);
}
}
Операции умножения и деления имеют приоритет перед сложением и вычитанием. Обратите внимание на действие операторов / и % при делении целых чисел, если в первом случае(оператор /) после деления осталась только целая часть, то во втором случае(оператор %) наоборот целая часть была отброшена, а в результате остался остаток 1 от деления 7 на 3.
Вам нужны ещё математические функции? Хорошо, вызывайте класс Math. Пример вот эта формулы:
В Java она будет выглядеть так:
double f = Math.abs(1.0 - Math.pow(x, 3.0)) /
(4.0 / 3.0 * Math.sqrt(y - Math.PI)));
Когда мы записываем целые и дробные числа, то мы выделяем это точкой. Например 3 целое, а 3.0 дробное.
Следующая программа выводить все целые числа от 1 до 10, не делящиеся без остатка на 3:
public class Sum {
public static void main(String[] args) {
int total = 0;
for (int n = 1; n <= 10; n++) {
if (n % 3 != 0) {
total = total + n;
System.out.println(total);
}
}
System.out.println("Total: " + total);
}
}
В итоге получим 1, 2, 4, 5, 7, 8, 10 и их сумму 37.
Усложним задачу #4: Изменим последнюю программу и выведем на экран числа не делящиеся без остатка на 4.
Если вам нужны подробности какие ещё функции доступны в классе Math:
docs.oracle.com/javase/7/docs/api/java/lang/Math.html
Но что делать, если 15 знаков после запятой не достаточно? Тогда вам нужны типы BigInteger и BigDecimal, это классы для проведения расчётов с очень высокой точностью. Если необходимо, то сто, тысячу или миллион знаков после запятой. Пример:
import java.math.BigDecimal;
public class HighPrecision {
public static void main(String[] args) {
BigDecimal a = new BigDecimal("2.7182818284"
+ "590452353602874713526624977572"
+ "4709369995"); // 50 decimal places
BigDecimal b = new BigDecimal("3.1415926535"
+ "89793238462643383279502884197169399"
+ "375105820974944"); // 60 dec. places
System.out.println("e*pi="
+ a.multiply(b));
}
}
Запустите программу и вы всё увидите сами.
Пара бит о строках
У вас уже была возможность в каждом из наших примеров познакомится с использованием строк. Тип String, это последовательность букв, чисел и символов. Самый простой пример «Hi John!». Но чаще всего строки используются для поиска участков текста или компоновки больших сообщений из нескольких частей. Для этого можно использовать знак +, он объединит несколько строк в одну:
String qty = "50";
String message = "I found " + qty + " books.";
Если надо получить часть строки, то используем метод substring. У каждого символа строки есть положение. Нумерация идёт 0. В следующем примере надо получить слово «house», его символы расположены от 4 до 8 позиции:
String line = "The house is blue.";
String word = line.substring(4, 8 + 1);
Ну, а если надо узнать, где именно начало слова «house», тогда применяем indexOf:
String line = "The house is blue.";
int position = line.indexOf("house"); // 4
int red = line.indexOf("red)"; // -1
Обратите внимание indexOf пишется с заглавной «O». В последней строке примера мы пытаемся найти слов «red», но его нет и метод нам вернул -1.
Узнать длину строки можно с помощью метода length(). Для получения отдельных символов используем charAt(), следующий пример показывает, как разложить строку на символы и побуквенно вывести их на экран.
public class LetterByLetter {
public static void main(String[] args) {
if (args.length == 0) {
System.out.println("Please type"
+ " a word.");
} else {
String word = args[0];
for (int i = 0; i < word.length(); i++){
System.out.println(word.charAt(i));
}
}
}
}
После компилляции javac, запустим программу указав командной строке слово после имени нашего класса.
java LetterByLetter telephone
Как я уже говорил в прошлой статье, через переменную args, введённая при запуске строка, передаётся в вашу программу (в данном примере это «telephone»). Попробуйте не вводить это слово и результат выполнения будет другой. Управляющие конструкции обеспечивают работу программы так, что с начало получаем размер строки и только потом по порядку выбираем буквы.
Для работы с строками существует много методов. Более подробно это описано в документации docs.oracle.com/javase/7/docs/api/java/lang/String.html
Усложним задачу #5: Изменим предыдущий пример и сделаем каждую букву заглавной. Подсказка: используйте метод делающий сразу все буквы строки заглавными, этот метод можно найти в документации по ссылке выше.
Пара бит о логике
Логический тип boolean может иметь только два варианта значения переменной: true или false. Он чаще всего используется как индикатор или как переключатель для управляющих конструкций if, while или for. Пример объявления логической переменной:
boolean painted = false;
А так изменяем её значение:
painted = true;
Или используем для while:
while (painted) {
// do something
}
Ещё можно для логических переменных применять операторы ! (NOT), && (AND) и || (OR). Оператор ! возвращает обратное значение переменной. Оператор && возвращает true, если обе части выражения имеют значение true, а оператор || возвращает true, если хотя-бы одно из них равно true. Пример:
boolean a = true;
boolean b = false;
boolean c = !a; // false
boolean d = a || b; // true
boolean e = a && b; // false
boolean f = (!a && b) || a; // true
В будущем вам могут встретится операторы & и |. Это тоже операторы AND и OR, но для числовых переменных. Но версия операторов && и || более эффективна, так как нет разницы в расположении операндов. В следующем примере вы можете увидеть, что от места расположения операндов результат не зависит:
boolean g = a || b; // true
boolean h = b && a; // false
Числовые и строковые переменные также могут возвратить результат типа boolean. Это результат сравнения для управляющих конструкций. Пример:
int total = 156;
if (total > 100) {
// do something
}
Выражение в скобках сравнивает переменную total, если total больше 100, результат будет true, иначе false. Для сравнения двух чисел вы можете применить следующие шесть операторов:
== равно
!= не равно
> больше
< меньше
>= больше или равно
<= меньше или равно
Все возвращаемые значения будут типа boolean, и вы можете их комбинировать с другими операторами типа boolean, для примера:
int sides = 6;
boolean painted = false;
if (sides >= 4 && !painted) {
// paint it!
}
Заключение
В эту статью вошло несколько тем, и она получилась более сложной чем первая, но я постарался сделать так, чтобы её прочтения вы быстрее освоили основы Java.
В следующей статье мы познакомимся с методами, классами и объектами Java, с некоторыми библиотеками классов входящих в Java. После чего вы сможете сделать программу генерирующую карту.
Автор: Svininykh