Опубликован: 11.12.2003 | Уровень: специалист | Доступ: платный
Лекция 13:

Пакет java.lang

< Лекция 12 || Лекция 13: 12345 || Лекция 14 >

Math

Класс Math состоит из набора статических методов, производящих наиболее популярные математические вычисления, и двух констант, имеющих особое значение в математике, – это число Пи и основание натурального логарифма. Часто этот класс еще называют классом-утилитой (Utility class). Так как все методы класса статические, нет необходимости создавать экземпляр данного класса, потому он и не имеет открытого конструктора. Нельзя также и наследоваться от этого класса, так как он объявлен с модификатором final.

Итак, константы определены следующим образом:

  • public static final double Math.PI – задает число \pi ("пи");
  • public static final double Math.E – основание натурального логарифма.

В таблице 13.2 приведены все методы класса и дано их краткое описание.

Таблица 13.2. Методы класса Math и их краткое описание.
Возвращаемое значение Имя метода и параметры Описание
abs(… a) абсолютное значение (модуль) для типов double, float, int, long
double acos(double a) арккосинус
double asin(double a) арксинус
double atan(double a) арктангенс
double ceil(double a) наименьшее целое число, большее a
double floor(double a) наибольшее целое число, меньшее a
double IEEEremainder (double a, double b) остаток по стандарту IEEE 754 (подробно рассматривался в лекции 3)
double sin(double a) синус (здесь и далее: аргумент должен быть в радианах)
double cos(double a) косинус
double tan(double a) тангенс
double exp(double a) e в степени a
double log(double a) натуральный логарифм a
max(… a, … b) большее из двух чисел (для типов double, float, long, int )
min(… a, … b) меньшее из двух чисел (для типов double, float, long, int )
double pow(double a, double b) a в степени b
double random() случайное число от 0.0 до 1.0
double rint(double a) значение int, ближайшее к a
round(… a) значение long для double ( int для float ), ближайшее к a
double sqrt(double a) квадратный корень числа a
double toDegrees(double a) преобразование из радианов в градусы
double toRadians(double a) преобразование из градусов в радианы

Строки

String

Этот класс используется в Java для представления строк. Он обладает свойством неизменяемости. После того как создан экземпляр этого класса, его содержимое уже не может быть модифицировано.

Существует много способов создать объект String. Наиболее простой, если содержимое строки известно на этапе компиляции, – написать текст в кавычках:

String abc = "abc";

Можно использовать и различные варианты конструктора. Наиболее простой из них – конструктор, получающий на входе строковый литерал.

String s = new String("immutable");

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

public class Test {
  public Test() {
  }

  public static void main(String[] args) {
    Test t = new Test();
    String s1 = "Hello world !!!";
    String s2 = "Hello world !!!";
    System.out.println("String`s equally = " +
	                   (s1.equals(s2)));
    System.out.println(
        "Strings are the same = " + (s1==s2));
  }
}

В результате на консоль будет выведено:

String`s equally = true
Strings are the same = true

Теперь несколько модифицируем код:

public class Test {
  public Test() {
  }
  public static void main(String[] args) {
    Test t = new Test();
    String s1 = "Hello world !!!";
    String s2 = new String("Hello world !!!");
    System.out.println("String`s equally = " +
                       (s1.equals(s2)));
    System.out.println(
        "Strings are the same = " + (s1==s2));
  }
}

В результате на консоль будет выведено:

String`s equally = true
Strings are the same = false

Почему результат изменился? Дело в том, что создание нового объекта – это одна из самых трудоемких процедур в Java. Поэтому компилятор стремится уменьшить их количество, если это не приводит к непредсказуемому поведению программы.

В примере объявляются две переменные, которые инициализируются одинаковым значением. Поскольку класс String неизменяемый, их значения всегда будут одинаковыми. Это позволяет компилятору завести скрытую вспомогательную текстовую переменную, которая будет хранить такое значение, а все остальные переменные будут ссылаться на него же, а не порождать новые объекты. В результате в первом варианте программы создается лишь один объект String. Для большинства операций это несущественная разница. Исключение составляют действия, которые привязаны к конкретному объекту, а не к его значению. Например, методы wait/notify.

Во втором варианте указано динамическое обращение к конструктору. В этом случае компилятор уже не имеет возможности заниматься оптимизацией и JVM во время исполнения программы действительно создаст второй объект с точно таким же значением. Что мы и видим по результату выполнения примера.

В Java для строк определен оператор +. При использовании этого оператора производится конкатенация строк. В классе String также определен метод:

public String concat(String s);

Он возвращает новый объект-строку, дополненный справа строкой s.

Рассмотрим другой пример.

public class Test {
   public static void main(String[] args) {
      Test t = new Test();
      String s = "prefix !";
      System.out.println(s);
      s = s.trim();
      System.out.println(s);
      s = s.concat(" suffix");
      System.out.println(s);
   }
} 

prefix !
prefix !
prefix ! suffix

В данном случае может сложиться впечатление, что строку (объект String, на который ссылается переменная s ), можно изменять. В действительности это не так. В результате выполнения методов trim (отсечение пробелов в начале и конце строки) и concat создаются новые объекты-строки и ссылка s начинает указывать на новый объект-строку. Таким образом, меняется значение ссылки, объекты же неизменяемы.

Как уже отмечалось, строка состоит из двухбайтных Unicode-символов. Однако во многих случаях требуется работать со строкой как с набором байт (ввод/вывод, работа с базой данных и т.д.). Преобразование строки в последовательность байтов производится следующими методами:

  • byte[] getBytes() – возвращает последовательность байтов в кодировке, принятой по умолчанию (как правило, зависит от настроек операционной системы);
  • byte[] getBytes(String encoding) – возвращает последовательность байтов в указанной кодировке encoding.

Для выполнения обратной операции (преобразования байтов в строку) необходимо сконструировать новый объект-строку с помощью следующих методов:

  • String(byte[] bytes) – создает строку из последовательности байтов в кодировке, принятой по умолчанию;
  • String(byte[] bytes, String enc) – создает строку из последовательности байтов в указанной кодировке.

StringBuffer

Этот класс используется для создания и модификации строковых выражений, которые после можно превратить в String. Он реализован на основе массива char[], что позволяет, в отличие от String, модифицировать его значение после создания объекта.

Рассмотрим наиболее часто используемые конструкторы класса StringBuffer:

  • StringBuffer() – создает пустой StringBuffer ;
  • StringBuffer(String s) – буфер заполняется указанным значением s ;
  • StringBuffer(int capacity) – создает экземпляр класса StringBuffer с указанным размером (длина char[] ). Задание размера не означает, что нельзя будет оперировать строками с большей длиной, чем указано в конструкторе. На самом деле этим гарантируется, что при работе со строками меньшей длины дополнительное выделение памяти не потребуется.

Разница между String и StringBuffer может быть продемонстрирована на следующем примере:

public class Test {
   public static void main(String[] args) {
      Test t = new Test();
      String s = new String("ssssss");
      StringBuffer sb = 
	     new StringBuffer("bbbbbb");
      s.concat("-aaa");
      sb.append("-aaa");
      System.out.println(s);
      System.out.println(sb);
   }
}

В результате на экран будет выведено следующее:

ssssss
bbbbbb-aaa

В данном примере можно заметить, что объект String остался неизменным, а объект StringBuffer изменился.

Основные методы, используемые для модификации StringBuffer, это:

  • public StringBuffer append(String str) – добавляет переданную строку str в буфер;
  • public StringBuffer insert(int offset, String str) – вставка строки, начиная с позиции offset (пропустив offset символов).

Стоит обратить внимание, что оба метода имеют варианты, принимающие в качестве параметров различные примитивные типы Java вместо String. При использовании этих методов аргумент предварительно приводится к строке (с помощью String.valueOf() ).

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

public static void main(String[] args) {
StringBuffer sb = new StringBuffer("abc");
String str = sb.append("e").insert(4,
             "f").insert(3,"d").toString();
System.out.println(str);
}

В результате на экран будет выведено:

abcdef

При передаче экземпляра класса StringBuffer в качестве параметра метода следует помнить, что этот класс изменяемый:

public class Test {
  public static void main(String[] args) {
    Test t = new Test();
    StringBuffer sb = new StringBuffer("aaa");
    System.out.println("Before = " + sb);
    t.doTest(sb);
    System.out.println("After = " + sb);
  }
  void doTest(StringBuffer theSb){
    theSb.append("-bbb");
  }
}

В результате на экран будет выведено следующее:

Before = aaa
After = aaa-bbb

Поскольку все объекты передаются по ссылке, в методе doTest, при выполнении операций с theSB, будет модифицирован объект, на который ссылается sb.

< Лекция 12 || Лекция 13: 12345 || Лекция 14 >
Георгий Кузнецов
Георгий Кузнецов

1. По истечению срока курса, будет ли доступ к курсу закрыт? (в данном случае написано 29 января)

2. Так и не понял: что такое конструктор?

Вячеслав Лопачёв
Вячеслав Лопачёв

Хочу заново пройти курс. Можно ли как-то сбросить прогресс и обновить сертификат?

Данила Некрасов
Данила Некрасов
Россия, Пермь, ПНИПУ
Сергей Федоров
Сергей Федоров
Россия