Java. Інтерфейс BaseStream. Приклади використання методів інтерфейсу




Інтерфейс BaseStream. Приклади використання методів інтерфейсу

Перед вивченням даної теми рекомендується ознайомитись з наступною темою:


Зміст


Пошук на інших ресурсах:

1. Перелік методів інтерфейсу BaseStream

Нижче наведено перелік основних методів інтерфейсу BaseStream та їх призначення:

  • close() – закрити потік даних;
  • isParallel() – визначити чи потік є паралельним;
  • iterator() – отримати ітератор для потоку;
  • onClose() – задати обробник події закриття потоку;
  • parallel() – повернути паралельний потік даних;
  • sequential() – повернути послідовний потік даних;
  • spliterator() – отримати ітератор-розділювач;
  • unordered() – повернути невпорядкований потік даних.

  ⇑

2. Метод close(). Закриття потоку даних. Приклад

Щоб закрити потік даних використовується метод close(), який має наступну загальну форму

void close();

Обов’язково потрібно закривати тільки ті потоки даних, які зв’язані з файлами. Інші потоки даних закривати необов’язково.
У прикладі демонструється закриття потоку даних System.in, що слідує з клавіатурного вводу. Для вводу даних використовується клас Scanner. Спочатку формується масив цілих чисел, потім цей масив виводиться на екран. В кінці програми потік даних закривається методом close().

// Приклади відкриття/закриття потоку даних
import java.util.stream.*;
import java.util.*;

public class TrainStreamAPI {

  public static void main(String[] args) {

    // Метод close()
    // Отримати потік даних з клавіатури
    Scanner scanner = new Scanner(System.in);

    // Прочитати масив чисел. Кінець вводу - число 0
    Integer num;
    ArrayList<Integer> AL = new ArrayList();

    while (true) {
      System.out.print("num = ");

      // Отримати число з клавіатури
      num = scanner.nextInt();

      // Перевірити, чи не введено 0
      if (num==0) break;

      // Додати число до масиву
      AL.add(num);
    }

    // Вивести масив на екран
    System.out.println("End of input.");
    System.out.println("AL = " + AL);

    // Закрити потік scanner
    scanner.close();
  }
}

Результат роботи програми

num = 15
num = 18
num = -9
num = 3
num = 0
End of input.
AL = [15, 18, -9, 3]

  ⇑

3. Метод isParallel(). Визначення, чи потік даних паралельний. Приклад

Метод isParallel() призначений для визначення того, чи викликаючий потік даних є паралельний. Метод має наступну загальну форму:

boolean isParallel()

Метод повертає true, якщо потік даних паралельний. Якщо потік даних послідовний, то метод повертає false.
Текст програми, що демонструє використання методу isParallel() наступний.

import java.util.ArrayList;
import java.util.stream.*;

public class StreamAPI {

  public static void main(String[] args) {
    // Метод isParallel() - визначити, чи потік даних є паралельним

    // 1. Створити масив чисел, який буде потоком даних
    ArrayList<Integer> AL = new ArrayList<Integer>();
    for (int i=0; i<10; i++) {
      AL.add((int)(Math.random()*100)); // числа від 0 до 99
    }

    // 2. Вивести масив для контролю
    System.out.println(AL);

    // 3. Отримати послідовний потік даних з масиву AL
    Stream<Integer> stream = AL.stream();

    // 4. Визначити, чи потік stream є паралельним
    if (stream.isParallel())
      System.out.println("stream is parallel");
    else System.out.println("stream is not parallel");

    // 5. Отримати паралельний потік даних з масиву AL
    Stream<Integer> parallelStream = AL.parallelStream();

    // 6. Визначити, чи потік parallelStream є паралельним
    if (parallelStream.isParallel())
      System.out.println("parallelStream is parallel");
    else
      System.out.println("parallelStream is not parallel");
  }
}

Результат виконання програми

[48, 64, 30, 40, 19, 17, 27, 75, 48, 52]
stream is not parallel
parallelStream is parallel

  ⇑

4. Метод iterator(). Отримати ітератор для потоку даних. Приклад

Метод iterator() призначений для отримання ітератора. З допомогою ітератора можна переглядати елементи потоку та обробляти їх. Загальна форма методу наступна

Iterator<T> iterator()

тут

  • Iterator<T> – тип, що характеризує ітератор, який обробляє елементи деякого узагальненого типу T.

Метод є кінцевою операцією.

Текст програми, що демонструє метод iterator() наведено нижче.

import java.util.*;
import java.util.stream.*;
import java.util.function.*;

public class StreamAPI {

  public static void main(String[] args) {

    // 1. Створити набір чисел
    ArrayList<Double> AL = new ArrayList<Double>();
    AL.add(1.5);
    AL.add(2.8);
    AL.add(-2.3);
    AL.add(3.4);
    AL.add(1.1);

    // 2. Створити потік даних з набору чисел AL
    Stream<Double> stream = AL.stream();

    // 3. Отримати ітератор для потоку stream
    Iterator<Double> it = stream.iterator();

    // 4. Вивести елементи потоку з допомогою ітератора
    System.out.print("stream = ");
    while (it.hasNext()) {
      System.out.print(it.next()+" ");
    }
    System.out.println();

    // 5. Видалити від'ємні елементи потоку, утворити результуючий масив
    ArrayList<Double> AL2 = new ArrayList<Double>();
    double t;

    // Сформувати новий потік та отримати ітератор на нього
    stream = AL.stream();
    it = stream.iterator();

    // Цикл обходу потоку stream
    while (it.hasNext()) {
      // Отримати число з потоку
      t = it.next();

      // Якщо число додатнє, то додати його до масиву AL2
      if (t>=0.0)
        AL2.add(t);
    }

    // 6. Вивести масив AL2
    System.out.println("AL2 = " + AL2);
  }
}

Результат роботи програми

stream = 1.5 2.8 -2.3 3.4 1.1
AL2 = [1.5, 2.8, 3.4, 1.1]

  ⇑

5. Метод onClose(). Отримати потік з заданим обробником події закриття. Приклад

Метод onClose() дозволяє встановити обробник події закриття потоку – спеціальний метод, який буде викликатись при закритті потоку і виконувати деякі завершувальні дії. Метод onClose() має наступну загальну форму

S onClose(Runnable closeHandler)

тут

  • closeHandler – клас, що містить метод run() інтерфейсу Runnable. У методі run() вписується код, який потрібно виконати при закритті викликаючого потоку;
  • S – потік з встановленим обробником closeHandler;
    Після того, як обробник closeHandler встановлено, він викликається у випадку, коли викликаючий потік виконає метод close().

Приклад. У прикладі оголошується клас MyCloseStream, який виступає обробником, що викликається при закритті потоку.

Клас MyCloseStream реалізує інтерфейс Runnable. Це означає, що в класі обов’язково потрібно реалізувати єдиний метод run() інтерфейсу Runnable. У методі run() вписується код, що повинен виконуватись при закритті потоку. У програмі, в демонстраційних цілях, в методі run() виводиться просте інформаційне повідомлення.

Текст демонстраційної програми наступний.

import java.util.*;
import java.util.stream.*;

// Клас-обробник події закриття потоку.
class MyCloseStream implements Runnable {

  // Метод, що закриває потік
  public void run() {
    // Тут вписується код, що викликається при закритті потоку

    // Вивести деяке інформаційне повідомлення
    System.out.println("Close the stream.");

    // ...
  }
}

public class StreamAPI {

  public static void main(String[] args) {

    // Демонстрація виклику методу run() класу MyCloseStream
    // 1. Створити набір чисел
    ArrayList<Integer> AL = new ArrayList<Integer>();
    AL.add(25);
    AL.add(31);
    AL.add(22);
    AL.add(18);
    AL.add(11);

    // 2. Створити потік даних
    Stream<Integer> stream = AL.stream();

    // 3. Задати обробник закриття потоку
    MyCloseStream handler = new MyCloseStream();

    // 4. Викликати метод onClose() потоку stream і
    // передати йому обробник - екземпляр handler.
    stream.onClose(handler);

    // 5. Закрити потік:
    // викликається обробник закриття потоку
    stream.close(); // Close the stream
  }
}

Результат виконання програми

Close the stream.

  ⇑

6. Метод parallel(). Повернути паралельний потік даних. Приклад

Метод parallel() дозволяє отримати паралельний потік з викликаючого потоку. Якщо викликаючий потік вже є паралельним, то повертається цей потік. Метод parallel() є проміжною операцією і має наступну загальну форму:

S parallel()

тут

  • S – результуючий паралельний потік.

Текст програми, що демонструє метод parallel() наступний:

import java.util.*;
import java.util.stream.*;

public class StreamAPI {

  public static void main(String[] args) {

    // 1. Створити набір чисел
    ArrayList<Integer> AL = new ArrayList<Integer>();
    AL.add(20);
    AL.add(32);
    AL.add(12);
    AL.add(23);
    AL.add(51);

    // 2. Створити послідовний потік даних
    Stream<Integer> stream = AL.stream();

    // 3. Перевірити, що потік паралельний
    if (stream.isParallel())
      System.out.println("stream is parallel");
    else
      System.out.println("stream is sequential");

    // 4. Викликати метод parallel() - сформувати паралельний потік
    Stream<Integer> stream2 = stream.parallel();

    // 5. Вивести дані про потік
    if (stream2.isParallel())
      System.out.println("stream2 is parallel");
    else
      System.out.println("stream2 is sequential");
  }
}

Результат виконання програми

stream is sequential
stream2 is parallel

  ⇑

7. Метод sequential(). Повернути послідовний потік даних. Приклад

Метод sequential() дозволяє отримати послідовний потік з викликаючого потоку. Якщо викликаючий потік є послідовним, то повертається цей же потік. Метод є проміжною операцією. Метод має наступну загальну форму:

S sequential()

тут

  • S – результуючий послідовний потік.

Текст програми, що демонструє метод sequential() наведено нижче.

import java.util.*;
import java.util.stream.*;

public class StreamAPI {

  public static void main(String[] args) {
    // 1. Створити набір чисел
    ArrayList<Integer> AL = new ArrayList<Integer>();
    AL.add(20);
    AL.add(32);
    AL.add(12);
    AL.add(23);
    AL.add(51);

    // 2. Створити послідовний потік даних
    Stream<Integer> stream = AL.stream();

    // 3. Перевірити, що потік послідовний
    if (stream.isParallel())
      System.out.println("stream is parallel");
    else
      System.out.println("stream is sequential");

    // 4. Викликати метод sequential() - сформувати послідовний потік
    Stream<Integer> stream2 = stream.sequential();

    // 5. Вивести дані про потік stream2
    if (stream2.isParallel())
      System.out.println("stream2 is parallel");
    else
      System.out.println("stream2 is sequential");
  }
}

Результат виконання програми

stream is sequential
stream2 is sequential

  ⇑

8. Метод unordered(). Повернути невпорядкований потік даних. Приклад

Метод unordered() повертає невпорядкований потік даних на основі викликаючого потоку. Якщо викликаючий потік даних є невпорядкованим, то саме він і повертається.
Загальна форма методу наступна:

S unordered()

тут

  • S – результуючий невпорядкований потік.

Метод є проміжною операцією.

Текст програми, що демонструє метод unordered() наступний.

import java.util.*;
import java.util.stream.*;
import java.util.function.*;

public class StreamAPI {

  public static void main(String[] args) {
    // 1. Створити набір чисел
    ArrayList<Double> AL = new ArrayList<Double>();
    AL.add(1.5);
    AL.add(2.8);
    AL.add(-2.3);
    AL.add(3.4);
    AL.add(1.1);

    // 2. Створити потік даних з набору чисел AL
    Stream<Double> stream = AL.stream();

    // 3. Посортувати потік
    stream = stream.sorted();

    // 4. Вивести потік stream
    // 4.1. Оголосити дію, що виводить елемент типу Double
    Consumer<Double> action = (n) -> {
      System.out.print(n + " ");
    };

    // 4.2. Викликати метод forEach()
    System.out.print("Sorted Array AL = [");
    stream.forEach(action);
    System.out.println("]");

    // 5. Створити новий невпорядкований потік - метод unordered()
    stream = AL.stream().unordered();

    // 6. Вивести невпорядкований потік
    System.out.print("Unordered Array AL = [" );
    stream.forEach(action);
    System.out.println("]");
  }
}

  ⇑


Зв’язані теми

  ⇑