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("]");
  }
}

 


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