Гость
Map
Форумы / Java [игнор отключен] [закрыт для гостей] / Устройство Stream-ов / 25 сообщений из 33, страница 1 из 2
17.03.2020, 12:18
    #39938178
faustgreen
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Устройство Stream-ов
Как я понимаю стримы на данный момент:
Стрим можно представить в виде трубы с секциями, через которую движутся элементы. Эта труба имеет вентиль вначале, который открывается терминальной операцией. В каждой секции с элементом, что-то происходит, согласно инструкции, например:

Код: java
1.
2.
3.
4.
blocks.stream()
      .map(block ‑> block.squash())
      .filter(block ‑> block.getColor() != YELLOW)
      .forEach(block ‑> block.display());





С помощью метода peek можно увидеть это движение:
Код: java
1.
2.
3.
4.
5.
6.
7.
		Stream.of(1, 2, 3, 4, 5)
		      .peek((e) -> System.out.println("Stream element:" + e))
		      .filter((e)-> e>1)
		      .peek((e) -> System.out.println("Filtered element:" + e))
		      .map(String::valueOf)
		      .peek((e) -> System.out.println("Mapped element:" + e))
		      .collect(Collectors.toList());


результат:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
Stream element:1
Stream element:2
Filtered element:2
Mapped element:2
Stream element:3
Filtered element:3
Mapped element:3
Stream element:4
Filtered element:4
Mapped element:4
Stream element:5
Filtered element:5
Mapped element:5



Дополнительно:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
The intermediate operations are classifiable in:

Stateful
    distinct()
    sorted()
    limit (long l)
    skip (long l)

Stateless
    map (Function f)
    flatMap (Function f)
    filter (Predicate p)
    peek (Consumer c)



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

Я прав ?
...
Рейтинг: 0 / 0
17.03.2020, 12:25
    #39938183
PetroNotC Sharp
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Устройство Stream-ов
faustgreen
Но для сортировки элементов
это противоестественно для стрима и реактивного программирования
...
Рейтинг: 0 / 0
17.03.2020, 12:36
    #39938195
crutchmaster
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Устройство Stream-ов
faustgreen,

Stream - это типа стандартных потоков в *nix, только с типами и функциями.
...
Рейтинг: 0 / 0
17.03.2020, 12:36
    #39938197
crutchmaster
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Устройство Stream-ов
PetroNotC Sharp,

А вся эта труба на яве может работать параллельно? Т.е. filter в своём потоке, map в своём.
...
Рейтинг: 0 / 0
17.03.2020, 12:44
    #39938201
PetroNotC Sharp
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Устройство Stream-ов
crutchmaster
PetroNotC Sharp,

А вся эта труба на яве может работать параллельно? Т.е. filter в своём потоке, map в своём.
для чего?
Процессор будет переключать контекст, пыхтеть, работать. А смысл?
...
Рейтинг: 0 / 0
17.03.2020, 12:47
    #39938203
crutchmaster
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Устройство Stream-ов
PetroNotC Sharp,

Ну, с другой стороны - да.
...
Рейтинг: 0 / 0
17.03.2020, 12:49
    #39938204
PetroNotC Sharp
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Устройство Stream-ов
crutchmaster,
Думаю что стрим это разнесенный во времени процесс.
А процессор сам очень быстрый.
То есть проблема в медленном ПОЛУЧЕНИИ стрима.
Нечего параллелить.
Имхо
...
Рейтинг: 0 / 0
17.03.2020, 13:04
    #39938215
Alexander A. Sak
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Устройство Stream-ов
Читайте джавадоки.

java.util.stream...
All streams operations can execute either in serial or in parallel. The stream implementations in the JDK create serial streams unless parallelism is explicitly requested. For example, Collection has methods Collection.stream() and Collection.parallelStream(), which produce sequential and parallel streams respectively;...
...
Рейтинг: 0 / 0
17.03.2020, 13:08
    #39938216
faustgreen
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Устройство Stream-ов
PetroNotC Sharp, авторэто противоестественно для стрима и реактивного программирования
Из доков по стриму:
Код: java
1.
No storage. A stream is not a data structure that stores elements; instead, it conveys elements from a source such as a data structure, an array, a generator function, or an I/O channel, through a pipeline of computational operations.



Но операция sorted() должна же где то сохранить результат (насколько я знаю источник данных стрима не изменяется). Вот и интересно где это хранится, или возможно это работает как-то подругому?
...
Рейтинг: 0 / 0
17.03.2020, 13:17
    #39938222
faustgreen
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Устройство Stream-ов
Просто хочется понять абстрактную структуру стрима, чтобы действовать на уровне понимания, а не заучивания методов. Многие вещи потом будут сами вытекать. Например, что порядок операций имеет значение и лучше ставить filter в начале и т.д.
...
Рейтинг: 0 / 0
17.03.2020, 13:26
    #39938228
faustgreen
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Устройство Stream-ов
Переформулирую вопрос:
Как примерно буде выглядеть гифка из первого поста, если мы после команды filter() добавим команду sorted() ?
...
Рейтинг: 0 / 0
17.03.2020, 13:33
    #39938231
PetroNotC Sharp
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Устройство Stream-ов
faustgreen,
Сортировку что в бд, что в стримах делают в самом конце.
Например в бд перед выврдом на экран.
В стриме тоже сортируй при выводе toList()
В чем проблема?
Тоже самое что в бд.
...
Рейтинг: 0 / 0
17.03.2020, 13:35
    #39938232
PetroNotC Sharp
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Устройство Stream-ов
faustgreen
Переформулирую вопрос:
Как примерно буде выглядеть гифка из первого поста, если мы после команды filter() добавим команду sorted() ?
так же как при команде Count.
Поток УНИЧТОЖАЕТСЯ.
...
Рейтинг: 0 / 0
17.03.2020, 13:50
    #39938241
faustgreen
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Устройство Stream-ов
PetroNotC Sharp,

Набрасал простой код:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
Stream<Integer> stream = Stream.of(1, 2, 3);
		
long count = stream.count();
System.out.println(count);
//count = stream.count(); // java.lang.IllegalStateException: stream has already been operated upon or closed
		
Stream<Integer> stream2 = Stream.of(1, 2, 3);
		
Stream<Integer> stream3 = stream2.sorted();
// long count2 = stream2.count(); // java.lang.IllegalStateException: stream has already been operated upon or closed



На самом деле поток после sorted() закрывается... Просто думал, что это происходит только с терминальными операциями.
...
Рейтинг: 0 / 0
17.03.2020, 13:55
    #39938246
PetroNotC Sharp
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Устройство Stream-ов
faustgreen
На самом деле поток после sorted() закрывается...
ты по логике суди.
Как сортировать, если поток конец на дальнем востоке, а головка))) уже в москве)))
...
Рейтинг: 0 / 0
17.03.2020, 13:57
    #39938247
faustgreen
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Устройство Stream-ов
Zzz79, авторничего там не закрывается ,сортед не является терминальной операцией
Я не особо в этом секу, пока разбираюсь, но по факту стрим закрывается - если раскоментить код
Код: java
1.
// long count2 = stream2.count(); // java.lang.IllegalStateException: stream has already been operated upon or closed


ИДЕ брасает эксепшен, хотя терминальных операций со стоимом stream2 не было
...
Рейтинг: 0 / 0
17.03.2020, 14:01
    #39938252
PetroNotC Sharp
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Устройство Stream-ов
Zzz79,
Где твой код, учитель?
...
Рейтинг: 0 / 0
17.03.2020, 14:14
    #39938263
faustgreen
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Устройство Stream-ов
Zzz79
faustgreen

ИДЕ брасает эксепшен, хотя терминальных операций со стоимом stream2 не было

советую подучить стрим АПИ
ты пытаешься один стрим два раза поюзать?это очень интересно)


Да, похоже на то :
Код: java
1.
2.
3.
4.
		
Stream<Integer> stream4 = Stream.of(1, 3, 4, 0);
stream4.filter(e->e>0);
stream4.map(e->e); // Exception ...



Черт, я запутался.

К тому же появляются все новые и новые вопросы ... Например, если мы создадим лист со значениями и да потока, один будет в цикле добавлять новые элементы в лист, а второй в тоже самое время будет обрабатывать тот же лист через стреам:
List.stram.filter ....
В стриме будут только элементы на момент созадния стрима или также те, которые добавит второй поток ?
...
Рейтинг: 0 / 0
17.03.2020, 14:41
    #39938282
faustgreen
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Устройство Stream-ов
авторК тому же появляются все новые и новые вопросы ... Например, если мы создадим лист со значениями и да потока, один будет в цикле добавлять новые элементы в лист, а второй в тоже самое время будет обрабатывать тот же лист через стреам:
List.stram.filter ....
В стриме будут только элементы на момент созадния стрима или также те, которые добавит второй поток ?
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
		List<Integer> list = new ArrayList<>(100);
		for(int i=0; i<1000; i++)
			list.add(i);

		Thread t1 = new Thread(() -> {
			try {
				Thread.sleep(1000);
				for (int i=10;i<1000;i++) {
					list.add(i);
					System.out.println(Thread.currentThread().getName() + i);
				}	
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		});

		t1.start();
		Thread.sleep(1000);
		list.stream().peek(i->System.out.println(Thread.currentThread().getName())).forEach(System.out::println);


Словил:
Код: java
1.
2.
Exception in thread "main" java.util.ConcurrentModificationException
	at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(Unknown Source)



В общеме, много непонятного по теме стримов, ушел гуглить дальше...
...
Рейтинг: 0 / 0
17.03.2020, 14:42
    #39938283
faustgreen
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Устройство Stream-ов
Zzz79, авторя смогу попозже тебе нормально все объяснить,сейчас работой завалили)
Ок, спасибо!
...
Рейтинг: 0 / 0
17.03.2020, 14:44
    #39938285
PetroNotC Sharp
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Устройство Stream-ов
faustgreen
Код: java
1.
Stream<Integer> stream4 = Stream.of(1, 3, 4, 0);

вот этого в реальных проектах нет.
Зачем изучать сферического коня?
Дальше переходи к практике стримов.
...
Рейтинг: 0 / 0
17.03.2020, 15:34
    #39938318
faustgreen
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Устройство Stream-ов
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
		Integer[] array = new Integer[1100];
		for(int i=0; i<100; i++)
			array[i] = i;

		Thread t1 = new Thread(() -> {
			try {
				Thread.sleep(1100);
				for (int i=100;i<1000;i++) {
					array[i] = i;
					System.out.println(Thread.currentThread().getName() + ":" + i);
				}	
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		});

		t1.start();
		Thread.sleep(1000);
		Stream.of(array).peek(e->{
			try {
				Thread.sleep(1);
			} catch (InterruptedException e1) {
				e1.printStackTrace();
			}
		}).forEach(System.out::println);
		
		System.out.println(Arrays.toString(array));



Франмент вывода:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Thread-0:100
Thread-0:101
Thread-0:102
Thread-0:103

...

Thread-0:997
Thread-0:998
Thread-0:999
16
17
18
19
20
21
22

....

100
101

...


Получается, что стрим получает объекты для обработки из источника "на лету".
...
Рейтинг: 0 / 0
17.03.2020, 15:48
    #39938326
PetroNotC Sharp
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Устройство Stream-ов
faustgreen,
Ну и какой практический вывод с этими потоками?
Потоки не имеют отношения к стримам вообще.
...
Рейтинг: 0 / 0
17.03.2020, 15:55
    #39938330
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Устройство Stream-ов
Привет мои вирусные котаны-бротаны.

Безотносительно картинки. Факты.

1) Идея стрим-обработки информации идет еще со времен Unix. Изначально
unix-процессы можно соединять в цепочку. И фильтры и сортировки и процессинг.

Код: java
1.
$ process1producer | process2filter | .... | processConsumer



2) Очень сильно эта идея развита в функциональном программировании (ФП).
Если кто-то изучал устройство бесконечных рекурсивных ленивых функций-списков
в Lisp, Scala, Haskell то можно заметить что основа - это стрим. Причем
у него нет явного терминатора. Тоесть правильным трушным считается
именно такой стрим. Построить его на абстракциях языка (именно ЯЗЫКА)
Java невозможно т.к. в java изначально была заложена некая императивность
и отложенные калькуляции и хвостовая рекурсия не работают.

И хотя идя на встречу скорости и перформансу в Java затащили рядом с генериками
генераторы примитивов - они все равно реализованы библиотечно а не языково.
Тоесть язык java по прежнему остается императивным но с синтаксическим
сахаром о котором так долго просили Java разработчики которые завидовали Scala.
Теперь джависты горденько могут поглядывать по сторонам и хвастаться что
у них почти есть генераторы бесконечных последовательностей.

В топике 22002984 кривых Гилберта я предпринял наивную попытку сделать
такую ленивую последовательность на Scala. Мне там помогали но.. вроде что-то получилось.

Вобщем стримы - вторичны. Ленивые функции и хвостовая рекурсия - первичны.

По языку.

На титульной странички Хаскель приведена такая бесконечная последовательность
простых чисел в виде

Код: java
1.
2.
3.
primes = filterPrime [2..]
  where filterPrime (p:xs) =
          p : filterPrime [x | x <- xs, x `mod` p /= 0]


Причем эта последовательность - ленивая и если не использовать evaluate или тупые
сортировки - будет выдавать ровно столько простых чисел сколько потребуется.

3) У стримов есть хорошая аналогия. Курсоры баз данных. К сожалению не все
разработчики понимают преимущества курсоров. И постоянно норовят загрузить всю
выборку в коллекцию. Очень сильно в этом смысле подпортили ORM, т.к. они полностью
нивелировали идею курсоров и упростили ее до игр с коллекциями объектов. Причем
не с итератором или стримом а именно с самой безсмысленной и безпощадной
которая потребляет память.

И не все драйвера (особенно позорно в этом смысле отличается jdbc-postgres) умеют грамотно фетчить
forward-only курсоры. Некоторые внутри себя жрут память. А если им явно указать FORWARD - теряют
в производительности в десятки раз.

4) Картинка забавна и бесполезна. Она вобщем не отражает ни исторических препосылок стримов
ни требований. Кстати почитайте в API java-doc там есть рекомендация об иммутабельности источника.
...
Рейтинг: 0 / 0
17.03.2020, 16:01
    #39938333
faustgreen
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Устройство Stream-ов
PetroNotC Sharp
faustgreen,
Ну и какой практический вывод с этими потоками?
Потоки не имеют отношения к стримам вообще.


Пока спортивный интерес, хочу понять как там все устроено, а там может и польза будет.
Как например со строками:
String s = "";
s= s + "a";
s= s + "b";
s= s + "c";
...
Можно знать, что s= s + "b"; возвращает предыдущую строку + новую. Но зная внутреннюю структуру так делать не будешь.
...
Рейтинг: 0 / 0
Форумы / Java [игнор отключен] [закрыт для гостей] / Устройство Stream-ов / 25 сообщений из 33, страница 1 из 2
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]