
Беззнаковый сдвиг вправо
Часто требуется, чтобы при сдвиге вправо расширение знакового раз-ряда не происходило, а освобождающиеся левые разряды просто запол-нялись бы нулями.
public class ByteUShift {
static public void main(String args[]) {
char hex[] = { '0', '1', '2', '3', '4',
'5', '6', '7', '8', '9',
'а', 'b', 'с', 'd', 'e',
'f' };
byte b = (byte) 0xf1;
byte c = (byte) (b >> 4);
byte d = (byte) (b >> 4);
byte e = (byte) ((b & 0xff) >> 4);
System.out.println(" b = 0x" + hex[(b >> 4) & 0x0f] +
hex[b & 0x0f]);
System.out.println(" b >> 4 = 0x" + hex[(c >> 4) & 0x0f] +
hex[c & 0x0f]);
System.out.println("b >>> 4 = 0x" + hex[(d >> 4) & 0x0f] +
hex[d & 0x0f]);
System.out.println("(b & 0xff) >> 4 = 0x" +
hex[(e >> 4) & 0x0f] + hex[e & 0x0f]);
}
}
Битовые операторы присваивания
Так же, как и в случае арифметических операторов, у всех бинарных битовых операторов есть родственная форма, позволяющая автоматичес-ки присваивать результат операции левому операнду. В следующем примере создаются несколько целых переменных, с ко-торыми с помощью операторов, указанных выше, выполняются различ-ные операции.
public class OpBitEquals {
public static void main(String args[]) {
int a = 1;
int b = 2;
a |= 4;
b >>= 1;
System.out.println("a= " + a);
System.out.println("b= " + b);
}}
Операторы отношения
Для того, чтобы можно было сравнивать два значения, в Java имеется набор операторов, описывающих отношение и равенство. Список таких операторов приведен в таблице.
Оператор |
Результат |
== |
равно |
!= |
не равно |
> |
больше |
< |
меньше |
>= |
больше или равно |
<= |
меньше или равно |
Значения любых типов, включая целые и вещественные числа, символы, логические значения и ссылки, можно сравнивать, используя оператор проверки на равенство == и неравенство !=. Обратите внимание - в языке Java, так же, как в С и C++ проверка на равенство обозначается последовательностью (==). Один знак (=) - это оператор присваивания.
Булевы логические операторы
Булевы логические операторы, сводка которых приведена в таблице ниже, оперируют только с операндами типа boolean. Все бинарные логические операторы воспринимают в качестве операндов два значения типа boolean и возвращают результат того же типа.
Оператор |
Результат |
Оператор |
Результат |
& |
логическое И (AND) |
&= |
И (AND) с присваиванием |
| |
логическое ИЛИ (OR) |
= |
ИЛИ (OR) с присваиванием |
^ |
логическое исключающее ИЛИ (XOR) |
^= |
исключающее ИЛИ (XOR) с присваиванием |
|| |
оператор OR быстрой оценки выражений (short circuit OR) |
== |
равно |
&& |
оператор AND быстрой оценки выражений (short circuit AND) |
!= |
не равно |
! |
логическое унарное отрицание (NOT) |
?: |
тернарный оператор if-then-else |
Результаты воздействия логических операторов на различные комбинации значений операндов показаны в таблице.
А |
В |
OR |
AND |
XOR |
NOT A |
false |
false |
false |
false |
false |
true |
true |
false |
true |
false |
true |
false |
false |
true |
true |
false |
true |
true |
true |
true |
true |
true |
false |
false |
Программа, приведенная ниже, практически полностью повторяет уже знакомый вам пример BitLogic. Только но на этот раз мы работаем с булевыми логическими значениями.
public class BoolLogic {
public static void main(String args[]) {
boolean a = true;
boolean b = false;
boolean c = a | b;
boolean d = a & b;
boolean e = a ^ b;
boolean f = (!a & b) | (a & !b);
boolean g = !a;
System.out.println(" a = " + a);
System.out.println(" b = " + b);
System.out.println(" a|b = " + c);
System.out.println(" a&b = " + d);
System.out.println(" a^b = " + e);
System.out.println("!a&b|a&!b = " + f);
System.out.println(" !a = " + g);
}
Операторы быстрой оценки логических выражений (short circuit logical operators)
Существуют два интересных дополнения к набору логических опера-торов. Это - альтернативные версии операторов AND и OR, служащие для быстрой оценки логических выражений. Вы знаете, что если первый операнд оператора OR имеет значение true, то независимо от значения второго операнда результатом операции будет величина true. Аналогично в случае оператора AND, если первый операнд - false, то значение вто-рого операнда на результат не влияет - он всегда будет равен false. Если вы в используете операторы && и || вместо обычных форм & и |, то Java не производит оценку правого операнда логического выражения, если ответ ясен из значения левого операнда. Общепринятой практикой является использование операторов && и || практически во всех случаях оценки булевых логических выражений. Версии этих операторов & и | применяются только в битовой арифметике.
Тернарный оператор if-then-else
Общая форма оператора if-then-use такова: выражение1? выражение2: выражениеЗ
В качестве первого операнда - может быть использовано любое выражение, результатом которого является значение типа boolean. Если результат равен true, то выполняется оператор, заданный вторым операндом, то есть, . Если же первый операнд paвен false, то выполняется третий операнд - . Второй и третий операнды, то есть и , должны воз-вращать значения одного типа и не должны иметь тип void.
В приведенной ниже программе этот оператор используется для про-верки делителя перед выполнением операции деления. В случае нулевого делителя возвращается значение 0.
public class Ternary {
public static void main(String args[]) {
int a = 42;
int b = 2;
int c = 99;
int d = 0;
int e = (b == 0) ? 0 : (a / b);
int f = (d == 0) ? 0 : (c / d);
System.out.println("a = " + a);
System.out.println("b = " + b);
System.out.println("c = " + c);
System.out.println("d = " + d);
System.out.println("a / b = " + e);
System.out.println("c / d = " + f);
}
}
Строки
Для работы со строками в Java используется тип данных String.
Инициализация
Инициализируется этот тип данных также как и остальные примитивные типы.
String a;
Создаст новый объект типа String со значением по умолчанию равным null.
Команда
a = “Строка”;
Запишет в переменную a слово Строка.
String и char
Строку в Java можно рассматривать как некий массив символов типа char. Поэтому в Java есть простые способы получения каких-либо символов из строки. Пусть имеется переменная b типа char.
Команда
int I = a.indexOf(b);
Запишет в I номер первого вхождения символа b в встречаемой строке. Обратите внимание, что нумерация символов начинается не с 1 а с 0, поэтому если в приведенном выше примере символ b будет равен букве C, то в переменную I будет записано значение 0. В случае если искомый символ не встречается в строке, в переменную I будет записано значение -1.
Оператор lastIndexOf работает по тому же принципу, но возвращает номер последнего вхождения символа в строку.
Пусть имеется int i.
Команда
char c = a.charAt(i);
Запишет в переменную c символ стоящий на i-м месте в строке a. Здесь тоже не стоит забывать про особенности нумерации в Java. Если же длина строки меньше чем значение i, то программа рассмотрит такую попытку обращения как ошибку.
Получить длину строки(количество символов в ней) можно следующим образом:
Команда
Int I = a.length;
Запишет в переменную I длину строки a.
Также можно заменить все вхождения какого-либо символа в строку на другой символ. Пусть у нас есть строка a1, и нам нужно заменить все символы b1 на символ b2 и записать полученный результат в строку a2 . Это осуществляется с помощью следующей команды:
a1 = a2.replace(b1, b2);
Стоит заметить что если нужно заменить все элементы в исходной строке, без создания новой, то можно написать
a1 = a1.replace(b1, b2);
В Java также существует легкий способ переводить все символы в строке из нижнего регистра в верхний, и наоборот.
Команда
a = a.toLowerCase();
Заменит все символы верхнего регистра на символы нижнего регистра. Например, если мы применим этот оператор к строке из первого примера, то на выходе получим слово “строка”.
Оператор toUpperCase делает обратное, то есть в случае приведённого выше примера значение строки a станет “СТРОКА”.
Работа со строками
Также мы можем складывать строки друг с другом , сравнивать их, и получать подстроку данной строки.
Складывать строки можно также как и остальные примитивные типы данных. Пусть имеются строки а1 и а2, и их значения - “Стр” и “ока” соответственно.
Команда
a = a1 + a1;
Запишет в строку а1 слово “Строка”, являющееся “суммой” строк a1 и a2. Тот же самый результат будет при использовании команды
a = a1.concat(a2);
Команда
Int I = a1.compareTo(a2);
Запишет в переменную I значение меньше нуля в случае если лексикографически строка a1 меньше строки a2, и вернет значение большее нуля в обратном случае. Если же a1 лексикографически эквивалентна a2 то в I будет записано значение 0.
Пусть имеется строка a и число i.
Команда
String a1 = a.substring(i);
Запишет в строку a1 всю ту часть строки a которая начинается с символа с номером i. Также можно огранить подстроку и с другой стороны. Пусть у нас также имеется число j.
В таком случае команда
String a1 = a.substring(i, j);
Запишет в строку a1 часть строки a1 начинающуюся с символа с номером I и идущую до символа с номером j(не включая сам этот символ).
Команда
String myString = "My:name:is:Vova";
String[] splits = myString.split(":");
Разобьёт строку на массив слов. Выполните следующее задания:
- Переверните строку myString так что бы она выглядела вот так – «Vova:is:name:My»
- Переверните следующую строку «My:name:is:Vova:Petrov» аналогично первому заданию.
- Выполните следующее заданию с помощью класса StringBuilder.
- Как удалить в строке все пробелы? - Как узнать длину строки?
- Дана строка: « The String class represents character strings. All string literals in Java programs, such as "abc", are implemented as instances of this class. ». Вырежьте второе предложение и распечатайте его.
- В чем разница между классами String, StringBuffer/StringBuilder?
За дополнительной информацией обращайтесь в документацию. Папка «Doc» либо на официальный сайт Oracle.
Ввод/Вывод
Для ввода данных используется класс Scanner из библиотеки пакетов Java, .
Этот класс надо импортировать в той программе, где он будет использоваться. Это делается до начала открытого класса в коде программы.
В классе есть методы для чтения очередного символа заданного типа со стандартного потока ввода, а также для проверки существования такого символа.
Для работы с потоком ввода необходимо создать объект класса Scanner, при создании указав, с каким потоком ввода он будет связан. Стандартный поток ввода (клавиатура) в Java представлен объектом — System.in. А стандартный поток вывода (дисплей) — уже знакомым вам объектом System.out. Есть ещё стандартный поток для вывода ошибок — System.err.
import java.util.Scanner; // импортируем класс public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); // создаём объект класса Scanner int i = 2; System.out.print("Введите целое число: "); if(sc.hasNextInt()) { // возвращает истинну если с потока ввода можно считать целое число i = sc.nextInt(); // считывает целое число с потока ввода и сохраняем в переменную System.out.println(i*2); } else { System.out.println("Вы ввели не целое число"); } } }
Метод hasNextDouble(), применённый объекту класса Scanner, проверяет, можно ли считать с потока ввода вещественное число типа double, а метод nextDouble() — считывает его. Если попытаться считать значение без предварительной проверки, то во время исполнения программы можно получить ошибку (отладчик заранее такую ошибку не обнаружит). Например, попробуйте в представленной далее программе ввести какое-то вещественное число:
import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); double i = sc.nextDouble(); // если ввести букву s, то случится ошибка во время исполнения System.out.println(i/3); } }
Имеется также метод nextLine(), позволяющий считывать целую последовательность символов, т.е. строку, а, значит, полученное через этот метод значение нужно сохранять в объекте класса String. В следующем примере создаётся два таких объекта, потом в них поочерёно записывается ввод пользователя, а далее на экран выводится одна строка, полученная объединением введённых последовательностей символов.
import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); String s1, s2; s1 = sc.nextLine(); s2 = sc.nextLine(); System.out.println(s1 + s2); } }
Существует и метод hasNext(), проверяющий остались ли в потоке ввода какие-то символы.
В классе String существует масса полезных методов, которые можно применять к строкам (перед именем метода будем указывать тип того значения, которое он возвращает):
int length() — возвращает длину строки (количество символов в ней);
boolean isEmpty() — проверяет, пустая ли строка;
String replace(a, b) — возвращает строку, где символ a (литерал или переменная типа char) заменён на символ b;
String toLowerCase() — возвращает строку, где все символы исходной строки преобразованы к строчным;
String toUpperCase() — возвращает строку, где все символы исходной строки преобразованы к прописным;
boolean equals(s) — возвращает истинну, если строка к которой применён метод, совпадает со строкой s указанной в аргументе метода (с помощью оператора == строки сравнивать нельзя, как и любые другие объекты);
int indexOf(ch) — возвращает индекс символа ch в строке (индекс это порядковый номер символа, но нумероваться символы начинают с нуля). Если символ совсем не будет найден, то возвратит -1. Если символ встречается в строке нескольо раз, то вовзвратит индекс его первого вхождения.
int lastIndexOf(ch) — аналогичен предыдущему методу, но возвращает индекс последнего вхождения, если смивол встретился в строке несколько раз.
int indexOf(ch,n) — возвращает индекс символа ch в строке, но начинает проверку с индекса n (индекс это порядковый номер символа, но нумероваться символы начинают с нуля).
char charAt(n) — возвращает код символа, находящегося в строке под индексом n (индекс это порядковый номер символа, но нумероваться символы начинают с нуля).
public class Main { public static void main(String[] args) { String s1 = "firefox"; System.out.println(s1.toUpperCase()); // выведет «FIREFOX» String s2 = s1.replace('o', 'a'); System.out.println(s2); // выведет «firefax» System.out.println(s2.charAt(1)); // выведет «i» int i; i = s1.length(); System.out.println(i); // выведет 7 i = s1.indexOf('f'); System.out.println(i); // выведет 0 i = s1.indexOf('r'); System.out.println(i); // выведет 2 i = s1.lastIndexOf('f'); System.out.println(i); // выведет 4 i = s1.indexOf('t'); System.out.println(i); // выведет -1 i = s1.indexOf('r',3); System.out.println(i); // выведет -1 } }
Пример программы, которая выведет на экран индексы всех пробелов в строке, введённое пользователем с клавиатуры:
import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); String s = sc.nextLine(); for(int i=0; i < s.length(); i++) { if(s.charAt(i) == ' ') { System.out.println(i); } } } }
Домашнее задание:
Создать программу, которая будет выводить на экран меньшее по модулю из трёх введённых пользователем вещественных чисел.
Создать программу, которая будет проверять, является ли слово из пяти букв, введённое пользователем, палиндромом (примеры: «комок», «ротор»). Если введено слово не из 5 букв, то сообщать об ошибке. Программа должна нормально обрабатывать слово, даже если в нём использованы символы разного регистра. Например, слова «Комок» или «РОТОР» следует также считать палиндромами.
Создать программу, которая будет сообщать, является ли целое число, введённое пользователем, чётным или нечётным. Если пользователь введёт не целое число, то сообщать ему об ошибке.
Создать программу, которая будет вычислять и выводить на экран сумму двух целых чисел, введённых пользователем. Если пользователь некорректно введёт хотя бы одно из чисел, то сообщать об ошибке.
Полезные ссылки:
Java 2. Том 1. Основы - Хорстманн, Корнелл