Главная страница
Навигация по странице:

  • 41) Чем является Stream в контексте Java

  • 42) В каком пакете находится Stream

  • 43) Чем Stream отличается от итератора

  • 45) Из каких частей состоит использование стримов

  • 46) В каком случае нужно закрывать стрим

  • 48) Откуда можно получить стрим

  • 50) Разница методов .list() и walk() Что такое саплер-поставщик какой содержит метод Как динамически получать стрим

  • 61) Как получить стрим диапазона чисел

  • 63) Можно ли конкатенировать стримы если да то каким методом Можно ли получить [пустой стрим

  • 65) Как получить стрим из [массива

  • 68) Для чего терминальные операции Какие бывают и что делают

  • 69) Что такое [коллекторы

  • 70) Сколько раз можно вызывать терминльную операцию Один раз.71) Что такое метод референс

  • билеты модуль 7. 1 Функциональные интерфейсы, основные типы


    Скачать 184 Kb.
    Название1 Функциональные интерфейсы, основные типы
    Дата05.12.2022
    Размер184 Kb.
    Формат файлаdoc
    Имя файлабилеты модуль 7.doc
    ТипДокументы
    #828359
    страница3 из 4
    1   2   3   4

    39) К каким переменным и как можно обращаться в теле лямда-выражениях?

    Доступ к переменным внешней области действия из лямбда-выражения очень схож к доступу из анонимных объектов. Можно ссылаться на:

    1) неизменяемые (effectively final - не обязательно помеченные как final) локальные переменные;

    2) поля класса;

    3) статические переменные.

    К методам по умолчанию реализуемого функционального интерфейса обращаться внутри лямбда-выражения запрещено.

    effectively final локальные переменные

    В в лямбда-выражениях стоит использовать внешние (относительно выражения) неизменяемые значения, а не внешние переменные,

    значение и внутреннее состояние которых могут меняться. Под внешними неизменяемыми значениями, соответственно,

    подразумеваются effectively final локальные переменные и поля примитивных типов, а также effectively final объекты,

    внутреннее состояние которых не будет меняться.
    Связано это с тем, что Streams и лямбда-выражения проектировались из расчета на их многопоточное использование.

    //1 вариант параметрам лямбды, а также свободно объявлять и использовать любые переменные

    IntUnaryOperator squaer = x -> x * x;
    //2 вариант к полям(переменным) того класса в нутри котого объявлена лямбда, можно как читать, так и писать.

    IntSupplier sequense = () -> counter++;
    //3 вариант к переменным которые объявлены внутри метода где объявлена лямбда. Но есть ограничения переменные должны быть эффективно финальные

    // т.е. значение им должно присвоено ровно один раз до объявления лямбды, после чего оно менятся уже не может.(Типа мы написали final)

    int bonus = 10;

    IntUnaryOperator bonusAdder = (x) -> x + bonus;
    //трюк с обходом еденичной длинны

    int[] test = new int[] {0};//ссылка является эффективно финальной но на содержимое это не влияет.
    40) Что такое Stream? Какие бывают стримы (По разным критериям, например "конечные и бесконечные", последовательные и параллельные)

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

    цикла и условного оператора. И программа будет иметь, простую линейную структуру.(Владыкин)

    Стрим состаит из источника - (элементы) -> промежуточные операторв - (элементы) -> терминальный оператор

    !!! Важно обработка происходит от терминального источника

    Операторы можно разделить на две группы:

    Промежуточные или КОНВЕЕРНЫЕ операторы(“intermediate”, ещё называют “lazy”) — обрабатывают поступающие элементы и возвращают стрим.

    Промежуточных операторов в цепочке обработки элементов может быть много.

    Терминальные (“terminal”, ещё называют “eager”) — обрабатывают элементы и завершают работу стрима,

    так что терминальный оператор в цепочке может быть только один.

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

    При этом все промежуточные операции выполняются лениво и пока не будет вызвана конечная операция никаких действий на самом деле не происходит

    (похоже на создание объекта Thread или Runnable, без вызова start()).

    Стримы создаются на основе каких-либо источников, например классов из java.util.Collection.

    Операции над стримами могут выполняться как последовательно, так и параллельно.

    Потоки не могут быть использованы повторно. Как только была вызвана какая-нибудь конечная операция, поток закрывается.

    Ассоциативные массивы (maps), например, HashMap, не поддерживаются.

    Кроме универсальных объектных существуют особые виды стримов для работы с примитивными типами данных int, long и double: IntStream, LongStream и DoubleStream.

    Эти примитивные стримы работают так же, как и обычные объектные, но со следующими отличиями:
    используют специализированные лямбда-выражения, например, IntFunction или IntPredicate вместо Function и Predicate;

    поддерживают дополнительные конечные операции [sum(), average(), mapToObj().



    41) Чем является Stream в контексте Java?

    Обработчик потоков объекта

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

    Большинство операций потока принимают в качестве параметров какие-то лямбда-выражения,

    в функциональный интерфейс точное поведение по каждой операции.

    Большинство этих операций должны быть как [неинтерферирующими (non-interfering), так и лишенными состояния (stateless). Что это значит?
    [Неинтерферирующуя функция не изменяет основной источник данных потока. Например,

    в приведенном выше примере лямбда выражение не изменяет mList путем добавления или удаления элементов из коллекции.
    Лишенная состояния функция — выполнение операции является детерминированным, например,

    в приведенном выше примере лямбда-выражение не зависит от какой-либо изменяемой переменной или

    состояния из внешней среды, которая могла бы измениться во время выполнения.

    42) В каком пакете находится Stream?

    Средства работы с потоками данных Stream API являются составляющей пакета [java.util.stream.

    Данный пакет содержит набор потоковых интерфейсов, образующих иерархию.

    Базовым поточным интерфейсом является [BaseStream.

    43) Чем Stream отличается от итератора?

    [Итератор это простой обьект который умеет выдовать только один элемент по одному

    Стрим гораздо сложный и навароченный, у него огромное количество методлов

    он содержит не только средства обхода элементов

    1) описания

    2) обработки

    3) преобразования последовательности элементов

    44) Сравнение стримов с [коллекцией

    коллекции предпологают хранение элементов и соответственно конечны

    Стримы бесконечны

    коллекции часто предоставляют индивидуальный доступ(индекс, ключ)

    Стрим такого не позволяет

    колекции можно менять, добавлять либо удалять элементы в том числе через итератора

    А применение трансформации к Стриму, ни как не влияют на источник откуда берется информация

    45) Из каких частей состоит использование стримов?

    1) получение Стрима откуда будут браться элементы последовательно

    2) Ноль или более промежуточных преобразований. Стрим их запоминате но пока не выполняет

    3) Единственная терминальная иоперация запускающая вес процесс вычесления и которая должна стать его полезным результатом.

    4) Закрытие стрима вызвать метод Close, обязателен только в том случае, когда стрим выделял какието системные ресурсы.(файл, потоки) можно использовать в с трай ресурсами


    46) В каком случае нужно закрывать стрим?

    4) Закрытие стрима вызвать метод Close, обязателен только в том случае, когда стрим выделял какието системные ресурсы.(файл, потоки) можно использовать в с трай ресурсами

    47) Первый этап работы со стримом


    48) Откуда можно получить стрим?

    Получить стрим можно из любой коллекции с помощью стрим

    или получить из потока, с помощью метода lines();

    Из дерриктории на диске с пмомощью list(), walk();

    Получить из строчки с помощью метода shars()
    Стримы можно [пораждать динамически

    Например с помощью Supplier, который имеет один метод get()

    Итерирование какойто функции

    Диапазон в виде стрема

    1) от начало диапазона до конца не в ключительно(0 - 99)

    2) от начала до конца включительно(0 - 100)

    Конкатенации двух других Стримов

    Или взять пустой стрим

    из массива

    указать явно

    1) Из коллекции:

    Stream fromCollection = Arrays.asList("x", "y", "z").stream();

    Стрим из List: list.stream()

    Стрим из Map: map.entrySet().stream()

    2) Из набора значений:

    Stream fromValues = Stream.of("x", "y", "z");

    3) Из массива:

    Stream fromArray = Arrays.stream(new String[]{"x", "y", "z"});

    4) Из файла (каждая строка в файле будет отдельным элементом в стриме):

    Stream fromFile = Files.lines(Paths.get("input.txt"));

    5) Из строки:

    IntStream fromString = "0123456789".chars();

    6) С помощью Stream.builder():

    Stream fromBuilder = Stream.builder().add("z").add("y").add("z").build();

    7) С помощью Stream.iterate() (бесконечный):

    Stream fromIterate = Stream.iterate(1, n -> n + 1);

    8) С помощью Stream.generate() (бесконечный):

    Stream fromGenerate = Stream.generate(() -> "0");

    9) Создание паралельного стрима

    collection.parallelStream() Stream stream = collection.parallelStream();



    50) Разница методов .list() и walk() Что такое саплер-поставщик? какой содержит метод? Как динамически получать стрим?

    Files.[list() возвращает массив файлов в указанной директории

    Files.[walk() возвращает поток файлов в указанной директории и субдиректориях

    Из опыта скажу, что list(); метод подразумевает когда мы указываем ему, где нужно проходить List возвращает список либо String либо File

    А метод walk(); сам идет в поддериктории ему просто надо указать на какую глубину нужно идти

    прогулка walk();

    public static Stream
    walk(Path start,

    FileVisitOption... options)

    throws IOException

    DoubleStream doubleStream = DoubleStream.generate(Math::random);//сеплаер поставщик

    [Supplier (с англ. — поставщик) — функциональный интерфейс, который не принимает никаких аргументов, но возвращает некоторый объект типа T:
    который представляет собой оператор, предоставляющий значение для каждого вызова.

    Supplier имеет только один метод get() и не имеет метода по умолчанию.

    Supplier

    IntSupplier int getAsInt();

    DoubleSupplier double getAsDouble();

    LongSupplier long getAsLong();

    BooleanSupplier boolean getAsBoolean();


    61) Как получить стрим диапазона чисел?
    IntStream smalInteger = IntStream.[range(0, 100);//Не выдает
    IntStream smallInteger2 = IntStream.range[Closed(0, 100); выдает последний элемент

    62) В чем разница методов range и [rangeClosed?

    в том, что первый не выдает последний элемент

    а второй выдает.


    63) Можно ли конкатенировать стримы? если да то каким методом? Можно ли получить [пустой стрим?

    да можно!

    IntStream cobiedStream = IntStream.concat(stream1,stream2);//конкатенация

    IntStream empty = IntStream.[empty();//пустой стрим взять с 9 джава
    64) Отличия Абстрактного класса от интерфейса

    Фундаментальная разница между интерфейсом и абстрактным классом заключается в том, что интерфейс определяет только поведение. Он не сообщает ничего про объект, который будет его реализовывать.

    Например, такое поведение как «движение» может быть применимо к разным типам объектов: машина, кот, котировки курса и т. д. Эти объекты не имеют ничего общего, кроме того, что они могут двигаться.

    Перефразируем немного иначе — если существует «движущийся» объект, то глядя на реализованный им интерфейс, мы не сможем понять, какой именно тип объекта имеется ввиду.

    Это может быть машина, кот, котировка курса валют и много других вариантов.

    Если перенести это поведение в код, написанный на языке Java, то получится следующее:

    interface Movable {

    void move();

    }

    Абстрактный же класс описывает некий абстрактный объект (автомобиль, человека, кота и т. д.), а не только поведение.

    Если мы рассуждаем про абстрактный «автомобиль», то в нашей голове сразу формируется картинка с объектом. Мы сразу понимаем, что автомобиль содержит двигатель,

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

    Вы получите все это просто сказав слово «автомобиль».

    При этом кот и котировка курса валют не могут быть автомобилем, даже если они также могут двигаться.


    65) Как получить стрим из [массива?

    double[] array = ...;

    DoubleStream doubleStream1 = Arrays.stream([array);//или из массива

    66) Какой второй этап работы со стримом?

    Применение промежуточных методов.

    //в качестве промежуточной операции можно встроить peek(Consuver) с помощью него можно посмотреть какие объекты летают на разных этапах обработки

    для отладки можно передовать System.out::println

    67) Перечислить основные промежуточные операции. Их предназначение.

    [Map() - Любое изменение исходного элемента можно делать с помощью метода map(). В качестве параметра метод принимает лямбда-выражение.

    [filter() - Отсеивание части объектов

    [sorted() -

    [peek()- доступ к элементу, не изменяя его, например вывести лог.

    [flatMap() -

    [skip() пропустить эл.

    [limit() ограничивает оставшиеся элементы


    68) Для чего терминальные операции? Какие бывают и что делают?

    Терминальные (“terminal”, ещё называют “eager”) — обрабатывают элементы и завершают работу стрима,

    так что терминальный оператор в цепочке может быть только один.

    findFirst Возвращает первый элемент из стрима (возвращает Optional) collection.stream().findFirst().orElse(«1»)

    [findAny Возвращает любой подходящий элемент из стрима (возвращает Optional) collection.stream().findAny().orElse(«1»)

    [collect Представление результатов в виде коллекций и других структур данных collection.stream().filter((s) -> s.contains(«1»)).collect(Collectors.toList())

    count Возвращает количество элементов в стриме collection.stream().filter(«a1»::equals).count()

    [anyMatch Возвращает true, если условие выполняется хотя бы для одного элемента collection.stream().anyMatch(«a1»::equals)

    [noneMatch Возвращает true, если условие не выполняется ни для одного элемента collection.stream().noneMatch(«a8»::equals)

    [allMatch Возвращает true, если условие выполняется для всех элементов collection.stream().allMatch((s) -> s.contains(«1»))

    [min Возвращает минимальный элемент, в качестве условия использует компаратор collection.stream().min(String::compareTo).get()

    [max Возвращает максимальный элемент, в качестве условия использует компаратор collection.stream().max(String::compareTo).get()

    [forEach Применяет функцию к каждому объекту стрима, порядок при параллельном выполнении не гарантируется set.stream().forEach((p) -> p.append("_1"));

    [forEachOrdered Применяет функцию к каждому объекту стрима, сохранение порядка элементов гарантирует list.stream().forEachOrdered((p) -> p.append("_new"));

    [toArray Возвращает массив значений стрима collection.stream().map(String::toUpperCase).toArray(String[]::new);

    [reduce Позволяет выполнять агрегатные функции на всей коллекцией и возвращать один результат collection.stream().reduce((s1, s2) -> s1 + s2).orElse(0)

    Обратите внимание методы findFirst, findAny, anyMatch это short-circuiting методы,

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

    а не обходить весь изначальный стрим.

    Краткое описание терминальных методов работы со стримами
    findFirst Возвращает первый элемент из стрима (возвращает Optional) collection.stream().findFirst().orElse(«1»)
    findAny Возвращает любой подходящий элемент из стрима (возвращает Optional) collection.stream().findAny().orElse(«1»)
    collect Представление результатов в виде коллекций и других структур данных collection.stream().filter((s) -> s.contains(«1»)).collect(Collectors.toList())


    69) Что такое [коллекторы?

    [collect(). Он используется для того, чтобы перейти от потоков к привычным коллекциям — List, Set, Map и другим.
    В метод collect() нужно передать специальный объект — collector. Этот объект вычитывает все данные из потока,

    преобразует их к определенной коллекции и возвращает ее. А следом за ним эту же коллекцию возвращает и сам метод collect.
    Все это сделано довольно хитро: объект collector имеет тип Collector – у него аж три типа-параметра.

    Последний тип R — это обычно и есть тип вроде List.

    Поэтому компилятор может по этому типу подставить правильный тип результата самого метода collect().

    To[List() Объект, который преобразует поток в список — List

    To[Set() Объект, который преобразует поток во множество — Set

    [toMap() Объект, который преобразует поток в мэп — Map

    [joining() Склеивает элементы потока в одну строку

    [mapping() Преобразует элементы потока в Map

    [groupingBy() Группирует элементы, возвращает Map


    70) Сколько раз можно вызывать терминльную операцию?

    Один раз.



    71) Что такое метод референс?

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

    Ссылки на методы (Method [References) – это компактные лямбда выражения для методов у которых уже есть имя.

    2. Ссылка на статический метод

    3. Ссылка на нестатический метод конкретного объекта

    4. Ссылка на нестатический метод любого объекта конкретного типа

    5. Ссылка на конструктор
    ContainingClass::staticMethodName Ссылка на статический метод
    containingObject::instanceMethodName Ссылка на нестатический метод конкретного объекта
    ContainingType::methodName Ссылка на нестатический метод любого объекта конкретного типа
    ClassName::new Ссылка на конструктор

    72) В чем разница между foreach и foreach[Ordered

    void forEach(Consumer action) - выполняет указанное действие для каждого элемента стрима.

    void forEachOrdered(Consumer action) - Тоже выполняет указанное действие для каждого элемента стрима,

    но перед этим добивается правильного порядка вхождения элементов.

    Используется для параллельных стримов, когда нужно получить правильную последовательность элементов.
    1   2   3   4


    написать администратору сайта