Ревью 7. Ревью 7 - Функциональные Интерфейсы, Streams. Чем является Stream в контексте Java 3 Для чего нужен 3
Скачать 84.11 Kb.
|
Где находятся функциональные интерфейсы?Многие функциональные интерфейсы, предоставляемые Java8, находятся в пакете java.util.function. Сколько дефолтных методов и статических методов, статических полей в функциональном интерфейсе?Ограничений по количеству методов и полей в функциональном интерфейсе нет (кроме абстрактного метода). Основные типы функциональных интерфейсов.Predicate — функциональный интерфейс для проверки соблюдения некоторого условия. Если условие соблюдается, возвращает true, иначе — false. Содержит метод boolean test(T t). Consumer (с англ. — “потребитель”) — принимает в качестве входного аргумента объект типа T, совершает некоторые действия, но при этом ничего не возвращает. Содержит метод void accept(T t). Supplier (с англ. — поставщик) — не принимает никаких аргументов, но возвращает некоторый объект типа T. Содержит метод T get(). Function —принимает аргумент T и приводит его к объекту типа R, который и возвращается как результат. Содержит метод R apply(T t); UnaryOperator — принимает в качестве параметра объект типа T, выполняет над ним некоторые операции и возвращает результат операций в виде объекта того же типа T. Содержит метод T apply(T t). BinaryOperator — принимает в качестве параметра два объекта типа T, выполняет над ними бинарную операцию и возвращает ее результат также в виде объекта типа T. Содержит метод T apply(T t1, T t2). Расскажите про Comparator и Comparable?Интерфейс Comparable используется только для сравнения объектов класса, в котором данный интерфейс реализован. Т.е. interface Comparable определяет логику сравнения объекта определенного ссылочного типа внутри своей реализации (по правилам разработчика). Comparator представляет отдельную реализацию и ее можно использовать многократно и с различными классами. Т.е. interface Comparator позволяет создавать объекты, которые будут управлять процессом сравнения (например, при сортировках). Какие есть способы инстанцировать функциональные интерфейсы?- создать экземпляр анонимного или именованного класса, реализующего интерфейс Function; - воспользоваться ссылкой на метод; - написать лямбда-выражение; Отличие BinaryOperator от FunctionFunction(функция) используется для преобразования входного параметра или в двух параметров (для BiFunction) в какое-либо значение, тип значение может не совпадать с типом входных параметров. BinaryOperator это разновидность Function, в которых входные и выходные обобщенные параметры должны совпадать. Если заглянуть в пакет java.util.function, то можно заметить, что UnaryOperator расширяет Function, а BinaryOperator расширяет BiFunction. Все способы реализации функционального интерфейса?В Java 8 функциональные интерфейсы могут быть представлены с использованием лямбда-выражений, ссылок на методы и ссылок на конструкторы. РазноеИмперативный vs декларативный подход.Декларативное программирование - парадигма программирования, в которой задаётся спецификация решения задачи, то есть описывается ожидаемый результат, а не способ его получения. Императивное программирование — это парадигма программирования, в которой задаётся последовательность действий, необходимых для получения результата. Декларативный стильТакой стиль, в котором вы описываете, какой именно результат вам нужен. И получатель такого сообщения уже сам разбирается, какие шаги для этого надо предпринять. Функциональное программирование- плюсы минусы, где применяется.Функциональное программирование помогает сделать код более понятным, предсказуемым и легким для чтения. Использование принципов функционального программирования помогает избавиться от ненужных абстракций с непредсказуемым поведением, поэтому сделать программу более предсказуемой и уменьшить количество возможных ошибок. ООП-подход подразумевает написание базовых классов и расширение существующих путем добавления к ним методов. Данные хранятся в экземпляре класса вместе с методами, которые ими оперируют. Функции в ООП зависят от внешних данных (например, содержат внутри себя ссылки на глобальные переменные) или коммуницируют с внешним миром (ввод-вывод). В отличие от ООП, функциональное программирование характеризуется слабой связью функции с данными, которыми она оперирует. Это позволяет избежать побочных эффектов при выполнении функций — например чтения и изменения глобальных переменных, операций ввода-вывода и так далее. Детерминированные функции ФП возвращают один и тот же результат для одних и тех же аргументов. Самое большое преимущество функционального программирования-краткость, потому что код может быть более кратким. Функциональная программа не создает переменную итератора в качестве центра цикла, поэтому этот и другие виды накладных расходов исключаются из вашего кода. Другим важным преимуществом является параллелизм, что легче сделать с функциональным программированием, поскольку компилятор заботится о большинстве операций, которые раньше требовали ручной настройки переменных состояния (например, итератора в цикле). Что такое StringJoiner?Класс StringJoiner используется, чтобы создать последовательность строк, разделенных разделителем с возможностью присоединить к полученной строке префикс и суффикс: StringJoiner joiner = new StringJoiner(".", "prefix-", "-suffix"); for (String s : "Hello the brave world".split(" ")) { joiner.add(s); } System.out.println(joiner); //prefix-Hello.the.brave.world-suffix Что такое Optional?Опциональное значение Optional — это контейнер для объекта, который может содержать или не содержать значение null. Такая обёртка является удобным средством предотвращения NullPointerException, т.к. имеет некоторые функции высшего порядка, избавляющие от добавления повторяющихся if null/notNull проверок: Optional optional.isPresent(); // true optional.ifPresent(s -> System.out.println(s.length())); // 5 optional.get(); // "hello" optional.orElse("ops..."); // "hello" Как вывести на экран 10 случайных чисел, используя forEach()?(new Random()).ints().limit(10).forEach(System.out::println); Как можно вывести на экран уникальные квадраты чисел используя метод map()?Stream.of(1, 2, 3, 2, 1).map(s -> s * s).distinct().forEach(System.out::println); Как вывести на экран количество пустых строк с помощью метода filter()?System.out.println(Stream.of("Hello", "", ", ", "world", "!").filter(String::isEmpty).count()); Как вывести на экран 10 случайных чисел в порядке возрастания?(new Random()).ints().limit(10).sorted().forEach(System.out::println); Как найти максимальное число в наборе?Stream.of(5, 3, 4, 55, 2).mapToInt(a -> a).max().getAsInt(); //55 Как найти минимальное число в наборе?Stream.of(5, 3, 4, 55, 2).mapToInt(a -> a).min().getAsInt(); //2 Как получить сумму всех чисел в наборе?Stream.of(5, 3, 4, 55, 2).mapToInt().sum(); //69 Как получить среднее значение всех чисел?Stream.of(5, 3, 4, 55, 2).mapToInt(a -> a).average().getAsDouble(); //13.8 Какие дополнительные методы для работы с ассоциативными массивами (maps) появились в Java 8?putIfAbsent() добавляет пару «ключ-значение», только если ключ отсутствовал: map.putIfAbsent("a", "Aa"); forEach() принимает функцию, которая производит операцию над каждым элементом: map.forEach((k, v) -> System.out.println(v)); compute() создаёт или обновляет текущее значение на полученное в результате вычисления (возможно использовать ключ и текущее значение): map.compute("a", (k, v) -> String.valueOf(k).concat(v)); //["a", "aAa"] computeIfPresent() если ключ существует, обновляет текущее значение на полученное в результате вычисления (возможно использовать ключ и текущее значение): map.computeIfPresent("a", (k, v) -> k.concat(v)); computeIfAbsent() если ключ отсутствует, создаёт его со значением, которое вычисляется (возможно использовать ключ): map.computeIfAbsent("a", k -> "A".concat(k)); //["a","Aa"] getOrDefault() в случае отсутствия ключа, возвращает переданное значение по-умолчанию: map.getOrDefault("a", "not found"); merge() принимает ключ, значение и функцию, которая объединяет передаваемое и текущее значения. Если под заданным ключем значение отсутствует, то записывает туда передаваемое значение. map.merge("a", "z", (value, newValue) -> value.concat(newValue)); //["a","Aaz"] Что такое LocalDateTime?LocalDateTime объединяет вместе LocaleDate и LocalTime, содержит дату и время в календарной системе ISO-8601 без привязки к часовому поясу. Время хранится с точностью до наносекунды. Содержит множество удобных методов, таких как plusMinutes, plusHours, isAfter, toSecondOfDay и т.д. Что такое ZonedDateTime?java.time.ZonedDateTime — аналог java.util.Calendar, класс с самым полным объемом информации о временном контексте в календарной системе ISO-8601. Включает временную зону, поэтому все операции с временными сдвигами этот класс проводит с её учётом. Как получить текущую дату с использованием Date Time API из Java 8?LocalDate.now(); Как добавить 1 неделю, 1 месяц, 1 год, 10 лет к текущей дате с использованием Date Time API?LocalDate.now().plusWeeks(1); LocalDate.now().plusMonths(1); LocalDate.now().plusYears(1); LocalDate.now().plus(1, ChronoUnit.DECADES); Как получить следующий вторник используя Date Time API?LocalDate.now().with(TemporalAdjusters.next(DayOfWeek.TUESDAY)); Как получить вторую субботу текущего месяца используя Date Time API?LocalDate .of(LocalDate.now().getYear(), LocalDate.now().getMonth(), 1) .with(TemporalAdjusters.nextOrSame(DayOfWeek.SATURDAY)) .with(TemporalAdjusters.next(DayOfWeek.SATURDAY)); Как получить текущее время с точностью до миллисекунд используя Date Time API?new Date().toInstant(); Как получить текущее время по местному времени с точностью до миллисекунд используя Date Time API?LocalDateTime.ofInstant(new Date().toInstant(), ZoneId.systemDefault()); Как определить повторяемую аннотацию?Чтобы определить повторяемую аннотацию, необходимо создать аннотацию-контейнер для списка повторяемых аннотаций и обозначить повторяемую мета-аннотацией @Repeatable: @interface Schedulers { Scheduler[] value(); } @Repeatable(Schedulers.class) @interface Scheduler { String birthday() default "Jan 8 1935"; } Что такое Nashorn?Nashorn - это движок JavaScript, разрабатываемый на Java компанией Oracle. Призван дать возможность встраивать код JavaScript в приложения Java. В сравнении с Rhino, который поддерживается Mozilla Foundation, Nashorn обеспечивает от 2 до 10 раз более высокую производительность, так как он компилирует код и передает байт-код виртуальной машине Java непосредственно в памяти. Nashorn умеет компилировать код JavaScript и генерировать классы Java, которые загружаются специальным загрузчиком. Так же возможен вызов кода Java прямо из JavaScript. Что такое jjs?jjs это утилита командной строки, которая позволяет исполнять программы на языке JavaScript прямо в консоли. Какой класс появился в Java 8 для кодирования/декодирования данных?Base64 - потокобезопасный класс, который реализует кодировщик и декодировщик данных, используя схему кодирования base64 согласно RFC 4648 и RFC 2045. Base64 содержит 6 основных методов: getEncoder()/getDecoder() - возвращает кодировщик/декодировщик base64, соответствующий стандарту RFC 4648; getUrlEncoder()/getUrlDecoder() - возвращает URL-safe кодировщик/декодировщик base64, соответствующий стандарту RFC 4648; getMimeEncoder()/getMimeDecoder() - возвращает MIME кодировщик/декодировщик, соответствующий стандарту RFC 2045. Как создать Base64 кодировщик и декодировщик?// Encode String b64 = Base64.getEncoder().encodeToString("input".getBytes("utf-8")); //aW5wdXQ== // Decode new String(Base64.getDecoder().decode("aW5wdXQ=="), "utf-8"); //input |