2015-04-22 2 views
5

Я читал на потоках Java 8 и способ передачи данных из источника данных, а не сбор всей коллекции для извлечения данных.Java 8 Stream vs Collection Storage

Эта цитата, в частности, я прочитал статью относительно потоков в Java 8.

«Нет хранение Streams не имеют для хранения ценностей;. Они несут значения из источника (который может представлять собой структуру данных, функцию генерации, канал ввода-вывода и т. д.) через конвейер вычислительных шагов ». Из источника: http://www.drdobbs.com/jvm/lambdas-and-streams-in-java-8-libraries/240166818?pgno=1

Я понимаю концепцию потоковых данных в от источника по частям. То, что я не понимаю, - это потоковая передача из коллекции, как нет хранилища? Коллекция уже существует в куче, вы просто передаете данные из этой коллекции, коллекция уже существует в «хранилище».

В чем разница между размерами памяти и размерами, если бы я просто прокрутил коллекцию со стандартом для цикла?

ответ

17

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

Давайте рассмотрим один из примеров из этой статьи:

int sum = shapes.stream() 
       .filter(s -> s.getColor() == BLUE) 
       .mapToInt(s -> s.getWeight()) 
       .sum(); 

Предположим, что shapes является Collection, который имеет миллионы элементов. Можно было бы предположить, что операция filter будет перебирать элементы из источника и создавать временную коллекцию результатов, которая также может иметь миллионы элементов. Операция mapToInt может затем перебирать эту временную коллекцию и генерировать ее результаты для суммирования.

Это не так, как это работает. Нет временной, промежуточной коллекции. Операции потока конвейерны, поэтому элементы, выходящие из filter, передаются через mapToInt и оттуда до sum без сохранения и считывания из коллекции.

Если источник потока не был коллекцией - скажем, элементы считывались из сетевой коллекции - вообще не должно быть никакого хранилища. Следующий трубопровод:

int sum = streamShapesFromNetwork() 
       .filter(s -> s.getColor() == BLUE) 
       .mapToInt(s -> s.getWeight()) 
       .sum(); 

может обрабатывать миллионы элементов, но не нужно хранить миллионы элементов в любом месте.

3

Подумайте о потоке в виде сопла, соединенного с резервуаром для воды, который является вашей структурой данных. Сопло не имеет собственного хранилища. Конечно, вода (данные), которую предоставляет поток, поступает из источника, который имеет хранилище, но сам поток не имеет хранилища. Подключение другого сопла (потока) к вашему резервуару (структура данных) не потребует хранения для всей новой копии данных.

+0

Спасибо за ответ! Я понимаю часть потоковой передачи данных, но что такое служебные данные памяти (хранилища), если я просто буду использовать коллекцию напрямую, а не потоковое? Если я использую коллекцию напрямую, я получаю доступ к коллекции в куче, если я ее передаю, я по-прежнему передаю данные из коллекции, находящейся в куче. В любом случае объем памяти остается неизменным в обоих методах. Пожалуйста, поправьте меня, если я ошибаюсь или что-то не хватает. – user3587411

+0

@ user3587411: По существу нет разницы. Один способ может использовать несколько кадров стека и временных объектов, но это всего лишь несколько байтов. – user2357112

+0

* «В любом случае след памяти остается неизменным в обоих методах». * Цель потока - не сохранять память. – Radiodef

3

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

Если у вас есть опыт работы с РСУБД - это то же самое понятие «вид».

0
  1. Коллекция представляет собой структуру данных. Основываясь на проблеме, вы решаете, какая коллекция будет использоваться как ArrayList, LinekedList (учитывая сложность времени и пространства). Где как Stream - это просто инструмент для обработки, который делает вашу жизнь легкой.

  2. Другая разница: вы можете рассмотреть Collection как в структуре данных в памяти, где вы можете добавить, удалить элемент. Где как в Поток Вы можете выполнять два вида операций:

    a. Промежуточная операция: Фильтр, карта, сортировка, ограничение по результирующему набору
    b. Операция терминала: forEach, собирайте результирующий набор в коллекцию.

    Но если вы заметили, с потоком вы не сможете добавлять или удалять элементы.

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

example1:

List<String> employeeNameList = Arrays.asList("John","Peter","Sachin"); 
    Stream<String> s = employeeNameList.stream(); 

    // iterate through list 
    s.dorEach(System.out :: println); // this work's perfectly fine 
    s.dorEach(System.out :: println); // you will get IllegalStateException, stating stream already operated upon 

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

Надеюсь, ясно.

Смежные вопросы