Ако извикам collect на последователен поток (напр. от извикване на Collection.stream()), тогава ще използва ли параметъра на комбиниране, който подавам, за събиране? Предполагам, че не, но не виждам нищо в документацията. Ако съм прав, тогава изглежда жалко да трябва да доставям нещо, което знам, че няма да се използва (ако знам, че е последователен поток).
Използва ли последователен поток в Java 8 параметъра за комбиниране при извикване на collect?
comment
Какво се случва, когато подадете null за комбинатора? Какво заключавате от този експеримент?
- person JB Nizet   schedule 13.06.2014
comment
@JBNizet Ще хвърли NullPointerException.
- person johnlinp   schedule 27.05.2020
Отговори (1)
Имайте предвид, че разработвате спрямо спецификациите на интерфейса -- не срещу изпълнението. Изпълнението може да се промени със следващата версия на Java, докато спецификацията трябва да остане стабилна.
Спецификацията не прави разлика между последователни и паралелни потоци. Поради тази причина трябва да приемете, че може да се използва комбинатор. Всъщност има добри примери, показващи, че комбинаторите за последователни потоци могат да подобрят производителността. Например следната операция намаляване свързва списък от низове. Изпълнението на кода без комбинатор има квадратична сложност. Интелигентното изпълнение с комбинатор може да намали времето за изпълнение с величини.
List<String> tokens = ...;
String result = tokens.stream().reduce("", String::concat, String::concat);
person
nosid
schedule
13.06.2014
Би било много умно, ако внедряването на
Stream
разпознае дали използването на комбинатора може да подобри производителността. По-големият риск обаче е самият разработчик да промени потока на паралелен в момент, когато е забравил за пропуснатия комбинатор...
- person Holger; 13.06.2014
@Holger Точно така, или друг разработчик предава поток към вашия код и този поток може да се промени, за да бъде паралелен в бъдеще.
- person Stuart Marks; 13.06.2014
Благодаря за вашият отговор. Имах същия проблем и въпреки че винаги се придържам към разработването срещу интерфейса, намирам за жалко, че няма проста версия на колектор без комбинатор. Това би направило нещата МНОГО по-лесни. Те можеха да направят
Collector.Characteristics
, за да укажат това, или по-проста версия на интерфейса Collector
...
- person glglgl; 03.09.2014
Още един въпрос: Ето аз намери изречението
A sequential implementation of a reduction using a collector would create a single result container using the supplier function, and invoke the accumulator function once for each input element.
Това вече не показва ли, че комбинаторът не се използва в тази ситуация?
- person glglgl; 03.09.2014
@Holger, @ nosid Не разбрах съвсем как комбинаторът, който споменахте в примера, ще подобри производителността в последователен поток. Според моето разбиране във всеки един момент има акумулиращ низ и елемент в потока. Просто ги свързваме и създаваме нов акумулиращ низ. Изпускам ли нещо?
- person GeekFactory; 21.11.2019
@GeekFactory пренебрегвате разходите за „просто ги свържете“. Конкатенацията на низове предполага създаване на нов низ, който е копие на двата аргументни низа. Колкото по-дълъг е низът, толкова повече са режийните. И междинният резултат от множество конкатенации на низове е низ, който става все по-дълъг и по-дълъг. Можете да потърсите „Алгоритъмът на художника Шлемиел“ за интуитивна картина. Вижте също ideone.com/0kRRnt Само за да стане ясно,
collect(joining())
все още е още по-добър, но се надявам, че виждате , използването на комбинатора намалява режийните разходи в този пример.
- person Holger; 21.11.2019
@Holger Уау! Това е чудесен пример за демонстрация на това как комбинаторът има смисъл в последователни потоци. Ако не греша
return reduce.apply(......)
работи като комбинатор, нали? Освен това има ли име за този алгоритъм, който използвате?
- person GeekFactory; 21.11.2019
@GeekFactory точно в този момент функцията действа като комбинатор. Това е еквивалентно на това, което прави Stream API, когато разделя работното натоварване за паралелни потоци. Когато става въпрос за име, бих казал, че е вариант на Разделяй-и- Победи.
- person Holger; 21.11.2019
Бихте ли предоставили, моля, подробен анализ или примери, показващи как това подобрява производителността? Или връзки към статии/изследвания?
- person Vyacheslav Babanin; 28.03.2021