Pull to refresh

Raspberry Pi и чашечку Java, пожалуйста! (Часть 2)

Reading time8 min
Views12K

Данная статья перевод второй части статей посвящённых использованию 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. Ещё, вы обратили внимание на червёртую строку? Хорошо, если заметили. Два знака плюс после переменной f увеличивают её на 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. После чего вы сможете сделать программу генерирующую карту.
Tags:
Hubs:
-4
Comments9

Articles