Новые статьи

CrudRepository в Spring Data

27 мая 2018

В статье Hibernate и Spring Boot мы рассматривали использование Hibernate для того, чтобы не писать sql-запросы в слое доступа к данным. Сегодня мы пойдём ещё дальше и рассмотрим, как Spring Data может генерировать за вас сам слой доступа к данным со всеми методами, которые вам нужны в сервисном слое.

В качестве примера возьмём сущность «Страна» с её названием в качестве единственного параметра и на примере этой сущности шаг за шагом создадим все необходимые операции для поиска, добавления, редактирования и удаления этой сущности. В СУБД postgres надо создать следующую таблицу:

CREATE TABLE country
(
  id serial,
  name character varying(50NOT NULL,
  CONSTRAINT country_id_pk PRIMARY KEY (id)
);

Теперь создадим типовой maven-проект и добавим в pom.xml необходимые зависимости. Полную версию файла можно посмотреть на github, ссылка в конце статьи.

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.5.12.RELEASE</version>
</parent>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>
    <dependency>
        <groupId>org.postgresql</groupId>
        <artifactId>postgresql</artifactId>
        <version>42.2.2.jre7</version>
    </dependency>
    <dependency>
        <groupId>javax.xml.bind</groupId>
        <artifactId>jaxb-api</artifactId>
        <version>2.3.0</version>
    </dependency>
</dependencies>

spring-boot-starter-web отвечает за обработку http-запросов, а spring-boot-starter-data-jpa предоставляет функционал доступа к данным. Также мы добавляем драйвер для работы с целевой СУБД.

Читать полностью...

Тэги: Hibernate, Java 8, PostgreSQL, Spring, Spring Boot, Spring Data, rest.


Hibernate и Spring Boot

20 мая 2018

Ранее мы уже рассматривали, как работать с базой данных через jdbc в статье Работа с БД в Spring Boot на примере postgresql. А сегодня возьмём Hibernate - самый популярный фреймворк для работы с БД - и убедимся, что он значительно облегчает реализацию типовых операций над сущностями.

Предположим, в БД у нас есть две сущности: страна и город. В одной стране может быть несколько городов (отношение «один-ко-многим»). Структура таблиц выглядит примерно так:

CREATE SEQUENCE country_id_seq;

CREATE TABLE country
(
  id integer NOT NULL DEFAULT nextval('country_id_seq'::regclass),
  name character varying(50NOT NULL,
  CONSTRAINT country_id_pk PRIMARY KEY (id)
);

CREATE SEQUENCE city_id_seq;

CREATE TABLE city
(
  id integer NOT NULL DEFAULT nextval('city_id_seq'::regclass),
  name character varying(50NOT NULL,
  country_id integer NOT NULL
);

И мы хотим совершать типовые действия над этими сущностями: просмотр всего списка, поиск по id, добавление, обновление и удаление записей. Для этого создадим типовой Spring Boot проект. В pom-файле нужно прописать следующий parent:

Читать полностью...

Тэги: Hibernate, Java, PostgreSQL, Spring, Spring Boot, maven, rest.


Работа с датой в Spring Boot

12 мая 2018

В предыдущих статьях мы уже создавали rest-приложение (Spring Boot Restful Service, Работа с БД в Spring Boot на примере postgresql). А теперь давайте рассмотрим, как работать с датой и временем в Spring Boot на уровне rest-запросов и на уровне БД.

Предположим, перед нами стоит задача фиксировать в специальной таблице все действия пользователя (регистрация, вход, выход и т.п.) Таблица для СУБД Postgres в самом простом случае будет выглядеть так:

CREATE TABLE user_action
(
   id serial NOT NULL
   action_date timestamp without time zone NOT NULL
   user_id integer NOT NULL
   action_type integer NOT NULL
   CONSTRAINT user_action_pk PRIMARY KEY (id)


Тип serial представляет собой поле, которое автоматически увеличивается на единицу для каждой новой записи, поэтому его удобно использовать в качестве первичного ключа для записи.

Тип timestamp without time zone позволяет хранить метку времени без привязки к часовому поясу.

user_id и action_type представляют собой числовые id пользователя и тип действия соответственно. В реальном приложении каждое из них должно быть внешним ключом на соответствующие таблицы, но в нашем примере для простоты такой привязки нет.

Читать полностью...

Тэги: Java, PostgreSQL, Spring Boot.


Коллекции в Java

8 мая 2018

Под коллекциями в программировании подразумевают объекты, которые хранят внутри себя какой-либо набор значений и предоставляют набор методов для обращения к этим значениям. В Java можно выделить 3 наиболее часто используемых типа коллекций: списки (list), наборы (set) и словари (map). При объявлении коллекции типизируются каким-либо типом, т.е. одна коллекция хранит данные одного типа.

Список (list)

Списки в Java реализуют интерфейс List, который, в свою очередь, расширяет интерфейс Collection. Список позволяет хранить любые значения, в том числе повторяющиеся. Итерация (обход) списка происходит в порядке добавления элементов. Т.е. элемент, добавленный первым, при итерации также будет первым.

List<String> list = new ArrayList<>();
list.add("яблоко");
list.add("ананас");
list.add("яблоко");
System.out.println(list); // На экране увидим: [яблоко, ананас, яблоко]

Две наиболее частые реализации интерфейса List - это ArrayList и LinkedList.

Читать полностью...

Тэги: Collections, Java.


Как получить параметры окружения в Java

7 мая 2018

Метод System.getProperties() возвращает список системных свойств (параметров окружения), доступных для данной виртуальной машины. Свойство представляет из себя пару «ключ-значение». Среди полученных свойств всегда можно обнаружить следующие:

Читать полностью...

Тэги: Java.


Настройка postgres для доступа по сети

6 мая 2018

Для того, чтобы открыть доступ по локальной сети с других машин к БД, которая развёрнута на данной, нужно отредактировать два файла: postgresql.conf и pg_hba. Привожу пример для своей операционной системы, основанной на Linux (Ubuntu) и postgresql 9.5.

В файле /etc/postgresql/9.5/main/postgresql.conf находим строку

listen_addresses = '*'

и раскомментируем её (убираем решётку в начале строки) или добавляем, если такой строки в этом файле нет.

Данный параметр говорит о том, чтобы обрабатывать все запросы, приходящие извне. В противном случае будут обрабатываться только локальные запросы.

Затем в файле /etc/postgresql/9.5/main/pg_hba.conf с правами администратора нужно указать, какие хосты имеют право подключаться к указанной БД и каким образом обеспечивается безопасность подключения.

Читать полностью...

Тэги: PostgreSQL.


Рекурсивный запрос на postgres

5 мая 2018

Рассмотрим составление рекурсивных запросов на PostgreSQL для иерархических данных на примере следующей таблицы:

create table hierarchy_example (
    id serial not null,
    name character varying(100),
    parent_id integer,
    constraint id_pk primary key (id)
)

Здесь поле parent_id содержит номер записи, которая является родительской по отношению к данной. Если parent_id = null, считаем, что это - корневой элемент иерархии.

Заполним таблицу данными:

insert into hierarchy_example (name, parent_id) values ('root'null);
insert into hierarchy_example (name, parent_id) values ('item1'1);
insert into hierarchy_example (name, parent_id) values ('item2'1);
insert into hierarchy_example (name, parent_id) values ('subitem1'2);

Теперь составим запрос для прохода по этой иерархии, от элемента с именем subitem1 до root. На каждой итерации будем добавлять новую строку во временную таблицу temp1.

Читать полностью...

Тэги: PostgreSQL.


Запуск задач по расписанию в Spring Boot

4 мая 2018

Часто в приложениях возникает необходимость выполнять некоторые действия по расписанию, а не по запросу извне. Первое, что приходит на ум - это планировщик cron. Но если вы пишете приложение, используя Spring Boot, то можете реализовать похожий функционал, добавив всего пару аннотаций.

В качестве примера давайте создадим простой maven-проект. Затем пропишем в pom-файле Spring Boot как родителя для данного проекта:

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.5.12.RELEASE</version>
</parent>

Также у вас должна быть секция build со стандартным содержимым:

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

Теперь добавим стандартный main-класс:

Читать полностью...

Тэги: Java, Spring, Spring Boot, maven.


Создание runnable jar файла с помощью maven

3 мая 2018

Понятие runnable jar или uber jar возникает тогда, когда вы задумываетесь о разворачивании вашего проекта на удалённом сервере. У вас должна быть уверенность в том, что в произвольном окружении, где окажется ваше приложение, в classpath будут все необходимые классы из используемых вами библиотек.

Конечно, никакой проблемы нет, если вы вообще не используете сторонние библиотеки. Но я уверен, что всё-таки используете, если только ваш проект не «Hello World».

Чтобы гарантировать наличие нужных версий всех библиотек, нам проще поставлять их вместе с нашим приложением. Для удобства развёртывания все библиотеки можно поместить в один jar-файл. Подробнее о том, что такое jar-архив и как его получить, мы рассматривали в статье Как скомпилировать исходники java вручную.

Рассмотрим конкретный пример. Пусть имеется приложение, которое использует класс StringUtils из популярного проекта Apache commons-lang3:

package ru.devmark;

import org.apache.commons.lang3.StringUtils;

public class Main {

    public static void main(String[] args) {
        System.out.println(StringUtils.isBlank(""));
    }
}

В pom-файле нашего maven-проекта должно быть прописано следующее:

Читать полностью...

Тэги: Apache, Java, maven.


Как обменять значения двух переменных без буфера

2 мая 2018

Если перед вами встанет задача обменять значения двух числовых переменных a и b между собой, скорее всего, вы сделаете это так:

int buffer = a;
a = b;
b = buffer;

То есть поменять значения одновременно нельзя, ибо одно из них затрётся. Чтобы этого не произошло, мы создаём новую буферную переменную, куда и помещаем на время одно из значений.

А что, если нам нужно обменять значения числовых переменных между собой, не создавая новых переменных?

Читать полностью...

Тэги: Java, головоломки.


Как скомпилировать исходники java вручную

1 мая 2018

В современной разработке многие рутинные процессы автоматизированы достаточно хорошо, поэтому вам не приходится каждый раз компилировать ваши исходники вручную. Я не сомневаюсь, что вы прекрасно знаете, как это делается. А для тех, кто забыл или решил освежить свои знания, рассмотрим небольшой пример.

Наш проект будет состоять всего из двух классов, причём один будет вызывать метод другого.

Класс Other, единственный метод которого выводит строку текста на экран:

package ru.devmark.helper;

public class Other {
    public String getMessage() {
        return "Привет, мир!";
    }
}

Сохраним этот текст как есть в файл, имя которого обязательно должно совпадать с именем класса, т.е. Other.java.

Читать полностью...

Тэги: Java.


Как сделать полный бэкап базы на postgres

30 апреля 2018

Для создания полного бэкапа базы на postgres воспользуемся утилитой pg_dump. Бэкап представляет собой текстовый файл с sql-синтаксисом. При этом данные вставляются в более компактном виде.

Перейдём в целевой каталог, в котором планируется сохранить файл бэкапа. Затем выполняем команду:

pg_dump имя_базы -h хост -p порт -U пользователь > имя_файла_бэкапа.sql

Разумеется, подключиться можно как к локальной базе, так и к базе, расположенной на сервере. После того, как файл создался, можем приступить к созданию копии.

Для начала создайте базу (её имя может быть любым), а также пользователя, имя которого должно совпадать с именем пользователя, который работает с исходной базой. Скорее всего, это имя, которое вы использовали для параметра -U в команде, указанной выше. Но точнее лучше посмотреть в полученном файле бэкапа. В скрипте создания таблиц можно увидеть строчку вида:

ALTER TABLE имя_базы OWNER TO имя_пользователя;

Читать полностью...

Тэги: PostgreSQL.


Удобные методы работы с Map

29 апреля 2018

В Java 8 базовый интерфейс Map расширился новыми полезными методами. На конкретных примерах я покажу, как приходилось работать с этим типом коллекций раньше, и как легко с ним стало работать теперь.

Обход всей коллекции в цикле

Для того, чтобы пройтись по всем элементам коллекции и вывести значения на экран, раньше мы бы писали такой код:

for (Map.Entry<String, String> entry : map.entrySet()) {
    System.out.println(entry.getValue());
}

В java 8 появился метод foreach(), который принимает лямбда-функцию из двух параметров: ключ и значение. Указанный выше код можно записать одной строкой:

map.forEach((k, v) -> System.out.println(v));

Читать полностью...

Тэги: Collections, Java 8.


Тестирование System.out.print в JUnit

28 апреля 2018

Предположим, что у вас имеется метод, который вместо логов просто выводит какой-то текст через стандартный поток вывода:

public class Example {

    public void doSomeLogic() {
        System.out.print("Test string");
    }
}

И перед вами встаёт задача написать юнит-тест на то, что данный метод действительно выводит данную строку. Для тестирования будем использовать библиотеку JUnit.

Если бы он просто возвращал её как результат своей работы, мы бы проверяли его через Assert.equals(). Но если мы хотим тестировать вывод, то перед началом теста нам надо создать свой собственный поток, подсунуть его как стандартный вывод, выполнить необходимые проверки, а затем вернуть всё обратно.

В качестве реализации потока будем использовать ByteArrayOutputStream, поскольку его можно легко преобразовать в строку. Тестовый класс будет выглядеть так:

Читать полностью...

Тэги: JUnit, Java.


Stream API в Java

28 апреля 2018

В Java 8 появилось довольно важное нововведение под названием Stream. И здесь имеются в виду не потоки ввода/вывода. Stream - это абстракция, позволяющая с любыми объектами работать как с потоками данных. Порой это чем-то похоже на выполнение запросов к БД. Рассмотрим несколько типовых задач, с которыми часто сталкивается каждый разработчик.

Объединение нескольких строк в одну

Наверняка вам приходилось генерить одну строку из нескольких других, разделённых запятыми. При этом после последнего элемента запятой быть не должно. Знакомо? В java 8 это делается так:

Stream.of("Linux""Windows""Mac")
    .collect(Collectors.joining(", ")));

Мы создаём новый поток из простых строк, а затем собираем их в одну при помощи метода collect(). В результате получим следующую строку:

Читать полностью...

Тэги: Collections, Java 8, Stream API.


Функции для работы с датой и временем в Oracle

27 апреля 2018

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

Преобразование строки в дату:

to_date ('01-01-1970''dd-mm-yyyy')

Форматирование даты в строку:

select to_char(sysdate, 'yyyy-mm-dd HH24:MI:SS'from dual

Timestamp, представленный целым числом, преобразуем в дату:

select to_date('01-01-1970''dd-mm-yyyy') + (1417320144396 / (24 * 60 * 60 * 1000)) from dual

Читать полностью...

Тэги: Oracle, SQL.


RowMapper и ResultSetExtractor в Spring Boot

27 апреля 2018

Spring Boot предоставляет два интерфейса для обработки выборки из БД: RowMapper и ResultSetExtractor. Давайте разберём их назначение, а также выясним, чем они различаются на примере справочника городов и стран.

RowMapper

Чаще всего при работе со списками в restful-сервисах, построенных на Spring Boot, вы будете использовать RowMapper. Этот класс обрабатывает отдельно каждую запись, полученную из БД, и возвращает уже готовый объект - модель данных. В большинстве случаев его вполне хватает.

Создадим простенький rest-контроллер, который будет возвращать список всех стран, которые заведены у нас в БД. Определение таблицы в СУБД postgres выглядит следующим образом:

CREATE TABLE public.country
(
  id serial,
  name character varying(50NOT NULL,
  CONSTRAINT country_pk PRIMARY KEY (id)
)

Здесь тип serial представляет собой обычный integer, который автоматически увеличивается на 1 при добавлении каждой новой записи. То есть нет нужды при вставке явно указывать id.

Добавим туда несколько стран для примера:

insert into country (name) values ('Германия'); -- id = 1
insert into country (name) values ('Франция');  -- id = 2
insert into country (name) values ('Италия');   -- id = 3

Читать полностью...

Тэги: Java 8, PostgreSQL, SQL, Spring Boot, rest.


Обновление записи через DELETE-запрос в Spring Boot

26 апреля 2018

В статье Работа с БД в Spring Boot на примере postgresql мы узнали как читать данные из БД. Но чтение данных - это лишь малая часть всех операций, которые встречаются в типичном java-приложении. Теперь попробуем создать полноценный rest-интерфейс для удаления ранее добавленных записей.

За основу возьмём наше приложение из указанной статьи. Оно состоит из трёх слоёв: dao (работа с БД), бизнес-логика приложения (service) и сам rest-интерфейс (controller), который обрабатывает входящий json и генерирует исходящий.

Начнём с доработки dao-слоя (интерфейс ProfileDao).

    void deleteProfileById(int id);

Для удаления нам достаточно знать только id записи.

В реализацию интерфейса dao (ProfileDaoImpl) добавим sql-запрос в виде константы, которую принято размещать в начале класса:

    private static final String SQL_DELETE_PROFILE = "delete from profiles where id = :id";

Читать полностью...

Тэги: Java, SQL, Spring Boot, rest.


Обновление записи через PUT-запрос в Spring Boot

25 апреля 2018

В статье Работа с БД в Spring Boot на примере postgresql мы узнали как читать данные из БД. Но чтение данных - это лишь малая часть всех операций, которые встречаются в типичном java-приложении. Теперь попробуем создать полноценный rest-интерфейс для обновления ранее добавленных записей.

За основу возьмём наше приложение из указанной статьи. Оно состоит из трёх слоёв: dao (работа с БД), бизнес-логика приложения (service) и сам rest-интерфейс (controller), который обрабатывает входящий json и генерирует исходящий.

Начнём с доработки dao-слоя (интерфейс ProfileDao).

    void updateProfile(String firstName, String secondName, int age, int id);

Для обновления нам потребуется указать id записи, а также остальные значимые поля.

В реализацию интерфейса dao (ProfileDaoImpl) добавим sql-запрос в виде константы, которую принято размещать в начале класса:

    private static final String SQL_UPDATE_PROFILE =
            "update profiles set first_name = :firstName, last_name = :lastName, age = :age where id = :id";

Читать полностью...

Тэги: Java, SQL, Spring Boot, rest.


Добавление записи через POST-запрос в Spring Boot

24 апреля 2018

В статье Работа с БД в Spring Boot на примере postgresql мы узнали как читать данные из БД. Но чтение данных - это лишь малая часть всех операций, которые встречаются в типичном java-приложении. Теперь попробуем создать полноценный rest-интерфейс для добавления новых записей, их модификации и удаления.

За основу возьмём наше приложение из указанной статьи. Оно состоит из трёх слоёв: dao (работа с БД), бизнес-логика приложения (service) и сам rest-интерфейс (controller), который обрабатывает входящий json и генерирует исходящий.

Начнём с доработки dao-слоя (интерфейс ProfileDao), где до сих пор был только один метод чтения данных.

    void insertProfile(String firstName, String secondName, int age);

При добавлении новой записи нам достаточно всего три поля. id будет сгенерирован в БД автоматически.

В реализацию интерфейса dao (ProfileDaoImpl) добавим sql-запросы в виде констант, которые принято размещать в начале класса:

    private static final String SQL_INSERT_PROFILE =
            "insert into profiles (first_name, last_name, age) values (:firstName, :lastName, :age)";

Читать полностью...

Тэги: Java, SQL, Spring Boot, rest.


Пример standalone-приложения на Spring

14 января 2018

Рассмотрим базовые возможности dependency injection (внедрения зависимостей), которые открывает нам Spring.

Создадим обычный maven-проект, где в pom.xml добавим сам Spring (артефакт spring-context) и секцию build со стандартным плагином maven-compiler-plugin, в котором указываем версию java в source и target.

<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>4.3.13.RELEASE</version>
    </dependency>
</dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <configuration>
                <source>1.8</source>
                <target>1.8</target>
            </configuration>
        </plugin>
    </plugins>
</build>

Теперь создадим главный класс TestApp, который будет точкой запуска приложения.

Читать полностью...

Тэги: Java, Java 8, Spring, Stream API, maven, ООП.


Выравнивание числа ведущими нулями

12 января 2018

Рассмотрим случай, когда у вас есть некое число, количество цифр в котором заранее неизвестно и вам необходимо, чтобы число всегда составляло 5 знаков, то есть нужно добавить необходимое количество нулей слева. Есть целых два способа сделать это.

Без использования сторонних библиотек

Если у вас небольшой проект и не хочется тянуть лишнюю зависимость, то используйте String.format():

System.out.println(String.format("%05d"42));

В результате мы увидим строку «00042». К недостаткам данного способа можно отнести то, что нужно помнить правила форматирования в методе String.format().

Читать полностью...

Тэги: Apache, Java, maven.


Генерация случайных чисел при помощи Stream API

10 января 2018

В Java 8 у класса java.util.Random появился набор удобных методов для генерации стримов (Stream) случайных чисел для всех основных числовых типов. Например:

private List<Integer> randomIntsGenerator() {
    return new Random()
            .ints(2516)
            .boxed()
            .collect(Collectors.toList());
}

Читать полностью...

Тэги: Collections, Java 8, Stream API.


Работа с БД в Spring Boot на примере postgresql

6 января 2018

Данная статья является продолжением Spring Boot Restful Service, где была бы раскрыта тема работы с БД в Spring Boot. Давайте рассмотрим эту тему подробнее на примере СУБД postgresql, а в качестве основы возьмём проект, который мы делали в той статье.

Напомню, что проект представляет из себя простой restful-service, который принимает GET-запрос по HTTP и возвращает профиль пользователя по его id. Сам профиль содержит кроме id также имя, фамилию и возраст. Поэтому создадим таблицу profiles в базе данных.

CREATE TABLE public.profiles
(
  id serial,
  first_name character varying(50NOT NULL,
  last_name character varying(50NOT NULL,
  age integer NOT NULL,
  CONSTRAINT profile_id_pk PRIMARY KEY (id)
);

insert into profiles (first_name, last_name, age) values ('Иван''Петров'23);

Для поля id можно использовать тип serial. Он представляет собой целое число, которое инкрементируется (увеличивается на 1) автоматически при вставке новой записи в таблицу.

Читать полностью...

Тэги: Java 8, PostgreSQL, SQL, Spring Boot, rest.


Spring Boot Restful Service

5 января 2018

Что мы получим в результате

Простой сервис на Spring Boot, который при выполнении get-запроса будет возвращать профиль пользователя в формате json в зависимости от id, который передаётся в запросе. При возникновении исключительных ситуаций (например, профиль не найден), пользователь получит соответствующий ответ.

Реализуем обработку get-запроса

Сразу оговорюсь, что здесь рассмотрю только создание самого веб-сервиса. Чаще всего, он будет обращаться к базе для получения профиля пользователя. Мы же этого здесь делать не будем, а только сымитируем загрузку профиля по id. Но всё, что касается взаимодействия по http, будет работать как положено.

Spring Boot позволяет просто и без лишних телодвижений создавать веб-сервисы. При этом конфигурацию служебных бинов он берёт на себя. Вы всегда можете переопределить дефолтное поведение, объявив тот или иной бин явно.

Давайте создадим maven-проект, в котором в качестве родительского проекта укажем spring-boot-starter-parent. Также нам потребуется добавить одну зависимость spring-boot-starter-web. Этого вполне достаточно для нашего проекта.

Читать полностью...

Тэги: Java, Spring, Spring Boot, maven, rest.


Передача null в перегруженный метод

4 января 2018

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

interface MyInterface {
    void doWork();
}

class MyBaseObject implements MyInterface {
    @Override
    public void doWork() {
        System.out.println("Base");
    }
}

class MyChildObject extends MyBaseObject {
    @Override
    public void doWork() {
        System.out.println("Child");
    }
}

Читать полностью...

Тэги: Java, ООП, головоломки.


Простой способ создания коллекций в Java 9

4 января 2018

Java 9 предоставляет новый способ создания read-only коллекций при помощи стандартных универсальных методов List.of(), Set.of() и Map.of().

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

 List<String> days = List.of(
                "понедельник",
                "вторник",
                "среда",
                "четверг",
                "пятница",
                "суббота",
                "воскресенье");

При этом при попытке модифицировать полученную коллекцию (например, добавить новый элемент) вы получите ошибку, т.к. в данном случае вы работаете с неизменямой коллекцией.

Читать полностью...

Тэги: Collections, Java 9.


Генерация N одинаковых элементов через Stream API

4 января 2018

Предположим, вы хотите сгенерировать N одинаковых элементов. Это очень легко сделать в Java при помощи Stream API. Рассмотрим следующий метод:

private List<String> repeatedValueGenerator(String text, int count) {
    return Stream.generate(() -> text)
            .limit(count)
            .collect(Collectors.toList());
}

Читать полностью...

Тэги: Collections, Java 8, Stream API.


Генерация строки на основе шаблона

4 января 2018

Предположим, вам нужно генерить текст по определённому шаблону. У вас есть заранее заготовленный текст, куда вы передаёте параметры для подстановки. Например, текст sms для клиента.

Самое первое, что приходит на ум - это воспользоваться методом String.format(). Как известно, он чувствителен к порядку следования элементов. Но что, если сам шаблон лежит у вас где-нибудь в базе данных и может измениться в любое время, а порядок параметров «зашит» в коде самого приложения? Согласитесь, было бы удобнее, чтобы каждый параметр подставлялся по имени, а не по порядку.

И тут первое, что приходит на ум - это метод String.replace(). Но чтобы не писать очередной велосипед, лучше воспользоваться классом org.apache.commons.lang3.text.StrSubstitutor из стандартной библиотеки Apache Common.

Читать полностью...

Тэги: Apache, Java, maven.


Произведение всех чисел в столбце таблицы одним SQL запросом

3 января 2018

Я думаю, каждый знает такую функцию SQL, как SUM(). Она позволяет посчитать сумму всех значений по определённому столбцу. Но что, если нам вдруг понадобится посчитать не сумму, а произведение всех значений?

Как ни странно, функция SUM() нам тоже пригодится. Как нам от произведения перейти к сумме? Вспомним начала матанализа: логарифм произведения равен сумме логарифмов. Будем использовать натуральный логарифм LN() в паре с функцией возведения экспоненты в степень EXP()

Привожу пример для postgresql, но должно работать и в других СУБД:

select exp(sum(ln(field))) from tab

Читать полностью...

Тэги: PostgreSQL, SQL, головоломки.