Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Java Новый топик    Ответить
Топик располагается на нескольких страницах: Ctrl  назад   1 [2]      все
 Re: Устройство Stream-ов  [new]
PetroNotC Sharp
Member

Откуда:
Сообщений: 4508
faustgreen
Stream<Integer> stream4 = Stream.of(1, 3, 4, 0);
вот этого в реальных проектах нет.
Зачем изучать сферического коня?
Дальше переходи к практике стримов.
17 мар 20, 14:44    [22100680]     Ответить | Цитировать Сообщить модератору
 Re: Устройство Stream-ов  [new]
faustgreen
Member

Откуда:
Сообщений: 377
		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));


Франмент вывода:
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

...

Получается, что стрим получает объекты для обработки из источника "на лету".
17 мар 20, 15:34    [22100717]     Ответить | Цитировать Сообщить модератору
 Re: Устройство Stream-ов  [new]
PetroNotC Sharp
Member

Откуда:
Сообщений: 4508
faustgreen,
Ну и какой практический вывод с этими потоками?
Потоки не имеют отношения к стримам вообще.
17 мар 20, 15:48    [22100726]     Ответить | Цитировать Сообщить модератору
 Re: Устройство Stream-ов  [new]
mayton
Member

Откуда: loopback
Сообщений: 45514
Привет мои вирусные котаны-бротаны.

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

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

$ process1producer | process2filter | .... | processConsumer


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

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

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

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

По языку.

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

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 там есть рекомендация об иммутабельности источника.
17 мар 20, 15:55    [22100732]     Ответить | Цитировать Сообщить модератору
 Re: Устройство Stream-ов  [new]
faustgreen
Member

Откуда:
Сообщений: 377
PetroNotC Sharp
faustgreen,
Ну и какой практический вывод с этими потоками?
Потоки не имеют отношения к стримам вообще.


Пока спортивный интерес, хочу понять как там все устроено, а там может и польза будет.
Как например со строками:
String s = "";
s= s + "a";
s= s + "b";
s= s + "c";
...
Можно знать, что s= s + "b"; возвращает предыдущую строку + новую. Но зная внутреннюю структуру так делать не будешь.

Сообщение было отредактировано: 17 мар 20, 16:01
17 мар 20, 16:01    [22100735]     Ответить | Цитировать Сообщить модератору
 Re: Устройство Stream-ов  [new]
mayton
Member

Откуда: loopback
Сообщений: 45514
faustgreen
PetroNotC Sharp
faustgreen,
Ну и какой практический вывод с этими потоками?
Потоки не имеют отношения к стримам вообще.


Пока спортивный интерес, хочу понять как там все устроено, а там может и польза будет.
Как например со строками:
String s = "";
s= s + "a";
s= s + "b";
s= s + "c";
...
Можно знать, что s= s + "b"; возвращает предыдущую строку + новую. Но зная внутреннюю структуру так делать не будешь.

Дизассемблируй байткод и посмотри что внутри.
Современные компилляторы 90% распознают это
как StringBuilder.
17 мар 20, 16:02    [22100736]     Ответить | Цитировать Сообщить модератору
 Re: Устройство Stream-ов  [new]
PetroNotC Sharp
Member

Откуда:
Сообщений: 4508
faustgreen
спортивный интерес
теория без практики мертва.
Баланс соблюдай.
17 мар 20, 16:05    [22100738]     Ответить | Цитировать Сообщить модератору
 Re: Устройство Stream-ов  [new]
Zzz79
Member

Откуда:
Сообщений: 66
мне бы ваши трудности))
я вот перевожу микросервис на 6й градл и новый бут
вот тут веселуха так веселуха
17 мар 20, 17:27    [22100810]     Ответить | Цитировать Сообщить модератору
 Re: Устройство Stream-ов  [new]
faustgreen
Member

Откуда:
Сообщений: 377
Погуглили немного про стримы, текущее понимание:
Картинка из первого поста вроде как правильная, т.е. стрим это цепочка операций через которую "пролетают" элементы поштучно.
Непонятки были с тем как в этой цепочке работает операция sorted и ей подобные. в этом посте нашел ответ:
Sorting a stream is necessarily an eager/blocking operation.
И тут.
sorted() is a stateful intermediate operation which has been implemented by buffering the entire contents and sorting it,
 before passing any elements to the downstream operations

Т.е. на этой операции происходит блокировка пока все элементы не достигнут этой операции.

Вот тут еще приведен императивный аналог стрим выражения:
List<String> result = Stream.of("java", "streams", "are", "great", "stuff")
    .filter(s -> {
                  System.out.println("filtering " + s);
                  return s.length()>=4;
                 })
    .map(s -> {
               System.out.println("mapping " + s);
               return s.toUpperCase();
              })
    .limit(3)
    .collect(Collectors.toList());
System.out.println("Result:");
result.forEach(System.out::println);


Императивный вариант:
String[] source = { "java", "streams", "are", "great", "stuff"};
List<String> result = new ArrayList<>();
int limit = 3;
for(String s: source) {
    System.out.println("filtering " + s);
    if(s.length()>=4) {
        System.out.println("mapping " + s);
        String t = s.toUpperCase();
        if(limit-->0) {
            result.add(t);
        }
        else break;
    }
}


Мне стало немного понятнее, может еще кому то пригордиться. А возможно я где то ошибся и меня поправят )
18 мар 20, 22:05    [22101813]     Ответить | Цитировать Сообщить модератору
 Re: Устройство Stream-ов  [new]
faustgreen
Member

Откуда:
Сообщений: 377
Пока разбирался заметил еще одну штуку:
public class InvocationOrder {
	  public static void main (String[] args) {
	        IntStream stream = IntStream.range(1, 5);
	        stream = stream.peek(i -> log("starting", i)).sorted().peek(i -> log("SORT:", i))
	                       .filter(i -> { log("filtering", i);
	                                      return i % 2 == 0;})
	                       .peek(i -> log("post filtering", i));
	        log("Invoking terminal method count.");
	        log("The count is", stream.count());
	        
	        System.out.println(); 
	        	        
	        IntStream stream2 = IntStream.range(1, 5).parallel();
	        stream2 = stream2.peek(i -> log("starting", i)).sorted().peek(i -> log("SORT:", i))
	                       .filter(i -> {
	                           log("filtering", i);
	                           return i % 2 == 0;
	                       })
	                       .peek(i -> log("post filtering", i));
	        log("Invoking terminal method count.");
	        log("The count is", stream2.count());
	    }
	  
	    public static void log (Object... objects) {
	        String s = LocalTime.now().toString();
	        for (Object object : objects) {
	            s += " - " + object.toString();
	        }
	        System.out.println(s);
	        // putting a little delay so that we can see a clear difference
	        // with parallel stream.
	        try {
	            Thread.sleep(1);
	        } catch (InterruptedException e) {
	            e.printStackTrace();
	        }
	    }
}

Если у нас источник сортированный то блокировки на операции сортед вроде как не происходит:
21:07:40.734 - Invoking terminal method count.
21:07:40.741 - starting - 1
21:07:40.742 - SORT: - 1
21:07:40.743 - filtering - 1
21:07:40.744 - starting - 2
21:07:40.745 - SORT: - 2
21:07:40.746 - filtering - 2
21:07:40.747 - post filtering - 2
21:07:40.748 - starting - 3
21:07:40.749 - SORT: - 3
21:07:40.750 - filtering - 3
21:07:40.751 - starting - 4
21:07:40.752 - SORT: - 4
21:07:40.754 - filtering - 4
21:07:40.755 - post filtering - 4
21:07:40.756 - The count is - 2

21:07:40.759 - Invoking terminal method count.
21:07:40.767 - starting - 4
21:07:40.770 - starting - 3
21:07:40.772 - starting - 1
21:07:40.772 - starting - 2
21:07:40.775 - SORT: - 2
21:07:40.774 - SORT: - 3
21:07:40.776 - filtering - 2
21:07:40.776 - filtering - 3
21:07:40.777 - post filtering - 2
21:07:40.777 - SORT: - 4
21:07:40.778 - SORT: - 1
21:07:40.778 - filtering - 4
21:07:40.779 - filtering - 1
21:07:40.779 - post filtering - 4
21:07:40.780 - The count is - 2


Если заменим IntStream.range(1, 5) на IntStream.of(8,4,7,1,3) то вывод будет:
21:10:11.934 - Invoking terminal method count.
21:10:11.955 - starting - 8
21:10:11.958 - starting - 4
21:10:11.959 - starting - 7
21:10:11.960 - starting - 1
21:10:11.974 - starting - 3
21:10:11.977 - SORT: - 1
21:10:11.978 - filtering - 1
21:10:11.979 - SORT: - 3
21:10:11.985 - filtering - 3
21:10:11.986 - SORT: - 4
21:10:11.987 - filtering - 4
21:10:11.988 - post filtering - 4
21:10:11.989 - SORT: - 7
21:10:11.990 - filtering - 7
21:10:11.993 - SORT: - 8
21:10:11.997 - filtering - 8
21:10:12.002 - post filtering - 8
21:10:12.007 - The count is - 2

21:10:12.009 - Invoking terminal method count.
21:10:12.018 - starting - 3
21:10:12.019 - starting - 1
21:10:12.020 - starting - 7
21:10:12.021 - starting - 4
21:10:12.022 - starting - 8
21:10:12.026 - SORT: - 4
21:10:12.027 - filtering - 4
21:10:12.028 - post filtering - 4
21:10:12.029 - SORT: - 8
21:10:12.030 - filtering - 8
21:10:12.036 - post filtering - 8
21:10:12.036 - SORT: - 3
21:10:12.038 - SORT: - 7
21:10:12.038 - filtering - 3
21:10:12.039 - filtering - 7
21:10:12.040 - SORT: - 1
21:10:12.041 - filtering - 1
21:10:12.042 - The count is - 2
18 мар 20, 22:10    [22101816]     Ответить | Цитировать Сообщить модератору
 Re: Устройство Stream-ов  [new]
mayton
Member

Откуда: loopback
Сообщений: 45514
Твои эксперименты не имеют смысла пока ты САМ не сделаешь из них свои правильные выводы.
18 мар 20, 22:17    [22101821]     Ответить | Цитировать Сообщить модератору
 Re: Устройство Stream-ов  [new]
faustgreen
Member

Откуда:
Сообщений: 377
mayton, Это последний пост в теме, со стримами вроде разобрался. Просто, как писал выше, не люблю бездумно использовать методы, а сечас вроде все уложилось в голове.
18 мар 20, 22:37    [22101830]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: Ctrl  назад   1 [2]      все
Все форумы / Java Ответить