Руководство по классу Java Integer

Статья из группы Java Developer
В данной статье мы поговорим о классе Integer. Рассмотрим такие вопросы:
  • что такое классы-обертки;
  • автоупаковка/распаковка примитивов;
  • работа класса Integer, его методы и константы.
Руководство по классу Java Integer - 1

Классы-обертки примитивных типов

Как известно, в Java есть различные типы данных, которые условно можно разделить на два блока:
  • примитивные;
  • ссылочные.
Примитивных типов данных в Java несколько:
  • целые числа — byte, short, int, long;
  • числа с плавающей точкой (вещественные) — float, double;
  • логический тип данных — boolean;
  • символьный тип данных — char.
У каждого примитивного типа данных есть свой класс-обертка. Ссылочный тип данных, который “оборачивает” своего примитивного младшего брата в Java-объект. Ниже приведены примитивные типы данных и соответствующие им классы обертки:
Примитивный тип Класс обертка
byte Byte
short Short
int Integer
long Long
float Float
double Double
boolean Boolean
char Character
В практическом смысле у примитивов и их классов-оберток много общего. Большинство операций выполняются идентично. Однако у классов-оберток есть ряд характеристик, не свойственных примитивам. Во-первых, это классы: при работе с классам- обертками мы работаем с объектами. Во-вторых (все последующее вытекает из пункта во-первых), данные объекты могут быть null. В-третьих классы-обертки предоставляют ряд констант и методов, упрощающих работу с определенным типом данных. В данной статье мы подробнее рассмотрим работу с классом Integer.

The Integer

Класс Integer — это класс-обертка примитивного типа int. Внутри данного класса содержится единственное поле типа int. Будучи классом оберткой, Integer предоставляет различные методы для работы с int, а также ряд методов для преобразования int в String и String в int. Ниже мы рассмотрим различные примеры работы с классом. Начнем с создания. Чаще всего используется (да и проще всего использовать) следующий вариант создания:

Integer a = 3; 
То есть инициализация Integer переменной в данном случае аналогична инициализации int переменной. Более того, Integer переменную можно проинициализировать значением int переменной:

int i = 5; 
Integer x = i;
System.out.println(x); // 5
В кейсе выше неявно происходит автоупаковка. Мы поговорим еще о ней ниже. Помимо вариантов инициализации, указанных выше, переменную Integer можно создать, как и прочие объекты, с использованием конструктора и ключевого слова new:

Integer x = new Integer(25);
System.out.println(x);
Однако так дольше писать и дольше читать, поэтому данный вариант наименее распространен. С Integer переменными можно делать все то, что и с int переменными. Их можно:
Складывать

Integer a = 6;
Integer b = 2;
Integer c = a + b;
System.out.println(c); // 8
Вычитать

Integer a = 6;
Integer b = 2;
Integer c = a - b;
System.out.println(c); // 4
Умножать

Integer a = 6;
Integer b = 2;
Integer c = a * b;
System.out.println(c); // 12
Делить

Integer a = 6;
Integer b = 2;
Integer c = a / b;
System.out.println(c); // 3
Инкрементировать

Integer a = 6;
a++;
++a;
System.out.println(a); // 8
Декрементировать

Integer a = 6;
a--;
--a;
System.out.println(a); // 4
Однако при всем этом нужно быть осторожным и помнить, что Integer — это ссылочный тип данных, и переменная данного типа может быть null. В таком случае (если переменная равна null) лучше воздержаться от арифметических операций (да и любых других, в которых null ничего хорошего не сулит). Приведем пример:

Integer a = null;
Integer b = a + 1; // Здесь мы упадем с "Exception in thread "main" java.lang.NullPointerException"
System.out.println(b);
Операции сравнения в основной массе проводятся также, как и в примитивном типе int:

Integer a = 1;
Integer b = 2;

System.out.println(a > b);
System.out.println(a >= b);
System.out.println(a < b);
System.out.println(a <= b);
Output:

false
false
true
true
Особняком стоит операция сравнения двух Integer переменных. И дело тут в том, что Integer — это ссылочный тип данных, и его переменные хранят ссылки на значения, а не сами значения (объекты). Проявления этого факта можно наблюдать при выполнении следующего фрагмента кода:

Integer a = 1;
Integer b = 1;
Integer c = new Integer(1);

System.out.println(a == b); // true
System.out.println(a == c); // false
Результат первого равенства будет true, а второго — false. Так происходит, потому что в первом случае мы сравниваем две переменные (“а” и “b”), которые хранят в себе ссылки на один и тот же объект. А во втором случае мы сравниваем две переменные, ссылающиеся на два разных объекта (при создании переменной “c” мы создали новый объект). Приведем еще 1 интересный пример:

Integer a = 1;
Integer b = 1;

Integer x = 2020;
Integer y = 2020;

System.out.println(a == b); // true
System.out.println(x == y); // false
Как мы видим, результат первого сравнения у нас true, а результат второго — false. Тут все дело в кэшировании. Все целые числа в промежутке от -128 до 127 включительно (данные значения можно кастомизировать) кэшируются. Поэтому когда мы создаем новую переменную и присваиваем ей целочисленное значение, лежащее в промежутке от -128 до 127, мы не создаем новый объект, а присваиваем переменной ссылку на уже созданный объект в кэше. Теперь, зная этот факт, пример выше не кажется таким уж мистическим. Переменные а и b ссылаются на один и тот же объект — объект из кэша. А во время инициализации переменных x и y мы каждый раз создавали новый объект, и данные переменные хранили в себе ссылки на разные объекты. А как известно, оператор == сравнивает значения переменных, а значением ссылочных переменных являются ссылки. Чтобы безошибочно проверять на равенство две Integer переменные, необходимо использовать (как бы банально это ни звучало) метод equals. Перепишем пример выше:

Integer a = 1;
Integer b = 1;

Integer x = 2020;
Integer y = 2020;

System.out.println(a.equals(b)); // true
System.out.println(x.equals(y)); // true

Автоупаковка и распаковка Integer

Что такое автоупаковка и распаковка? При создании новых Integer переменных мы использовали такую конструкцию:

Integer a = 2020;
Таким образом мы создавали новый объект без использования ключевого оператора new. Такое возможно благодаря механизму автоупаковки примитивного типа int. Обратная процедура проявляется при присваивании примитивной переменной int значения ссылочной Integer переменной:

Integer a = 2020;
int x = a;
В данном случае мы вроде бы присвоили ссылку (а именно — ссылка на объект является значением переменной “а”) примитивной переменной. Но по факту благодаря механизму автораспаковки в переменную “х” записалось значение 2020. Автоупаковка/распаковка — весьма распространенное явление в Java. Часто оно происходит само собой, иногда даже без ведома программиста. Но знать об этом явлении все же нужно. У нас на Javarush есть интересная статья на эту тему.

Константы класса Integer

Класс Integer предоставляет различные константы и методы для работы с целыми числами. В данном разделе мы более подробно рассмотрим некоторые из них на практике. Начнем с констант. В таблице ниже приведены все константы класса:
Костанта Описание
SIZE Количество битов в двузначной системе счисления, занимаемое типом int
BYTES Количество байтов в двузначной системе счисления, занимаемое типом int
MAX_VALUE Максимальное значение, которое вмещает в себя тип int
MIN_VALUE Минимальное значение, которое вмещает в себя тип int
TYPE Возвращает объект типа Class от типа int
Посмотрим на значения всех этих констант, выполнив следующий код:

public static void main(String[] args) {
        System.out.println(Integer.SIZE);
        System.out.println(Integer.BYTES);
        System.out.println(Integer.MAX_VALUE);
        System.out.println(Integer.MIN_VALUE);
        System.out.println(Integer.TYPE);
}
В результате получим следующий вывод:

32
4
2147483647
-2147483648
int

Методы класса Integer

А теперь кратко рассмотрим наиболее используемые методы класса Integer. Итак, “топ” возглавляют методы по преобразованию числа из строки, либо преобразованию строки из числа. Начнем с преобразований строки в число. Для этих целей служит метод parseInt, сигнатура ниже:
  • 
    static int parseInt(String s)
    
Данный метод преобразует String в int. Продемонстрируем работу данного метода:

int i = Integer.parseInt("10");
System.out.println(i); // 10
Если преобразование невозможно — например, мы передали слово в метод parseInt — будет брошено исключение NumberFormatException. У метода parseInt(String s) есть перегруженный собрат:
  • 
    static int parseInt(String s, int radix)
    
Данный метод преобразует параметр s в int. В параметре radix указывается, в какой системе счисления изначально записано число в s, которое необходимо преобразовать в int. Примеры ниже:

System.out.println(Integer.parseInt("0011", 2)); // 3
System.out.println(Integer.parseInt("10", 8));   // 8 
System.out.println(Integer.parseInt("F", 16));   // 15
Методы parseInt возвращают примитивный тип данных int. У данных методов есть аналог — метод valueOf. Некоторые вариации данного метода внутри себя просто вызывают parseInt. Отличие от parseInt в том, что результатом работы valueOf будет Integer, а не int. Рассмотрим ниже все варианты данного метода и пример его работы:
  • static Integer valueOf(int i) — возвращает Integer значением которого является i;
  • static Integer valueOf(String s) — аналогичен parseInt(String s), но результатом будет Integer;
  • static Integer valueOf(String s, int radix) — аналогичен parseInt(String s, int radix), но результатом будет Integer.
Примеры:

int a = 5;
Integer x = Integer.valueOf(a);
Integer y = Integer.valueOf("20");
Integer z = Integer.valueOf("20", 8);

System.out.println(x); // 5
System.out.println(y); // 20
System.out.println(z); // 16
Мы рассмотрели методы, позволяющие перевести String в int/Integer. Обратная процедура достигается с помощью методов toString. У любого Integer объекта можно вызвать метод toString и получить его строковое представление:

Integer x = 5;
System.out.println(x.toString()); // 5
Однако в связи с тем, что метод toString часто вызывается у объектов неявно (например, при передаче объекта на печать в консоль), данный метод редко используется разработчиками в явном виде. Есть также и статический метод toString, который принимает в себя int параметр и переводит его в строковое представление. Например:

System.out.println(Integer.toString(5)); // 5
Однако, как и не статический метод toString, использование статического в явном виде можно встретить редко. Более интересен статический метод toString, который принимает 2 целочисленных параметра:
  • static String toString(int i, int radix) — переведет i в строковое представление в системе счисления radix.
Пример:

System.out.println(Integer.toString(5, 2)); // 101
В классе Integer есть пару методов для нахождения максимума/минимума из двух чисел:
  • static int max(int a, int b) вернет наибольшее из значений среди переданных переменных;
  • static int min(int a, int b) вернет наименьшее из значений среди переданных переменных.
Примеры:

int x = 4;
int y = 40;

System.out.println(Integer.max(x,y)); // 40
System.out.println(Integer.min(x,y)); // 4
Руководство по классу Java Integer - 2

Заключение

В данной статье мы рассмотрели класс Integer. Поговорили о том, что это за класс, что такое классы обертки. Рассмотрели класс с практической точки зрения. Разобрали примеры арифметических операций, в том числе операций сравнения. Взглянули на тонкости сравнения двух Integer переменных, разобрали такое понятие как кэшированные объекты. Также, мы упомянули о таком явлении как автоупаковка/распаковка примитивных типов данных. Кроме того, мы успели рассмотреть некоторые методы класса Integer, а также некоторые константы. Привели примеры перевода чисел из одной системы счисления в другую.

Домашнее задание

  1. Изучить, какие еще есть методы класса Integer (изучать можно на сайте с официальной документацией), написать в комментариях, какой из изученных вами методов (без учета тех, которые приведены в статье) наиболее полезен по вашему мнению (будет использоваться вами наиболее часто). А также привести обоснование своего мнения.

    P.S. Тут нет правильных ответов, но данная активность позволит лучше изучить класс.

  2. Решить небольшую простенькую задачку для закрепления материала.

    У нас есть два числа:

    1100001001 — в двоичной системе счисления
    33332 — в пятеричной системе счисления

    Необходимо используя только методы класса Integer определить максимум среди двух данных чисел, а затем вывести разницу между максимальным и минимальным значением в троичной системе счисления.

  3. Перевести максимально возможное значение Integer в восьмеричную систему счисления и вывести на экран количество цифр в полученном числе (количество считать программно).

Комментарии (17)
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ
Sergei Kirianov Уровень 8, Bratislava, Slovakia
14 февраля 2022

Integer inTwo = Integer.parseInt("1100001001",2);          
Integer inFive=Integer.parseInt("33332",5);                
                                                           
System.out.println(inTwo);                                 
System.out.println(inFive);                                
System.out.println(Integer.max(inTwo,inFive));             
System.out.println(Integer.toString(Math.abs(inFive-inTwo),3));
                                                           
int max=Integer.MAX_VALUE;                                 
String countOfNumber=Integer.toString(max,8);              
System.out.println(countOfNumber.length());                
hamster🐹 Уровень 36, Москва, Russian Federation
6 ноября 2021
Очень добротная статья, которая помогла мне понять лучше класс Integer =) Однозначно в закладки) Спасибо!
Rendox Уровень 2, Днепр
16 июня 2021


        String a = "1100001001";
        String b = "33332";

        int aIn10 = Integer.parseInt(a,2);
        int bIn10 = Integer.parseInt(b,5);

        int max = Integer.max(aIn10,bIn10);
        int min = Integer.min(aIn10,bIn10);

        int odds = max - min;
        System.out.println("Odd within max and min in base 3 is " + Integer.toString(odds,3));
        System.out.println();

        String maxIntInOctal = Integer.toOctalString(Integer.MAX_VALUE);

        System.out.println("Integer.MAX_VALUE in octal is " + maxIntInOctal);
        System.out.println("Count of digits in the Integer.MAX_VALUE in octal is " + maxIntInOctal.length());

 
Вывод: Odd within max and min in base 3 is 2010222 Integer.MAX_VALUE in octal is 17777777777 Count of digits in the Integer.MAX_VALUE in octal is 11 Process finished with exit code 0
Лилия Лебединская Уровень 21, Воронеж
23 марта 2021
еще одна замечательная статья, которая помогает понять, что я делаю)) правда, в моем случае, задачи решить нереально сложно)
Anonymous #2507531 Уровень 11
2 февраля 2021
вторая задача вообще решаема? вылазит исключение For input string: "2341534" under radix 3 то есть я никак не могу перевести результат в троичную систему!!!
🦔 Виктор Уровень 20, Москва, Россия Expert
2 ноября 2020
Спасибо за добротную статью! Особенно познавательно было про кэшированные объекты. Статья интересна, но домашнее здание я, конечно же, делать не буду ; ) Лучше в нагрузку почитаю упомянутую статью про авто распаковку-упаковку. -- tlgrm: LetsCodeIt / SefoNotasi
Олеся Уровень 10
31 мая 2020
А что это за метод такой equals?
Vlad Уровень 22
27 мая 2020
Как конвертировать Integer в другую систему исчисления не перегоняя его в String? Как избавиться от такой конвертации? int x = Integer.parseInt("1100001001", 2); String a = Integer.toString(x, 3); int x3 = Integer.parseInt(a);
Александр Уровень 23, Москва, Россия
27 мая 2020
Большинство операцИИ Йвыполняются после таблицы: Примитивный тип - Класс обертка
MAX Уровень 16, Киров, Россия
26 мая 2020
Почему в примере метод equals выдал тру? Разве и его не надо переопределять? Разве у него по умолчанию не тот же самый ==?