Неправильный выбор дизайна для изменения состояния локального объекта из Lambda в Java? - PullRequest
0 голосов
/ 12 января 2020

Предположим, у меня есть это

Class1 instance = new Class1(); //this is "effectively final"
int [] arr = new int[]{1, 2, 3, 4, 5}; //array of ints

// modify "instance" with a lambda
Arrays.stream(arr).forEach(x -> instance.modifyInstanceStateWithNum(x));

Этот код будет работать, потому что instance эффективно является окончательным. Мне интересно, однако, если это неправильный код для использования и плохой дизайн, так как Lambdas, как я понимаю, в целом функциональны?

Альтернатива:

for(int num : arr){
  instance.modifyInstanceStateWithNum(num);
}

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

Ответы [ 2 ]

0 голосов
/ 15 января 2020

JavaDo c для Stream.foreach() выдает соответствующие предупреждения:

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

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

Тот факт, что Stream вообще имеет метод forEach (который не имеет смысла без побочные эффекты) намекает на то, что он не считается совершенно неупорядоченным.

Лично я бы проголосовал за использование для l oop, если потоки не дают вам существенного преимущества в удобочитаемости.

0 голосов
/ 12 января 2020

Потоки в java обычно более краткие. В строгом смысле они должны способствовать меньшей изменчивости и, следовательно, не изменять состояния вашего объекта. Однако в противном случае и последовательные потоки, и a для l oop делают одно и то же. исх. TDD java

Есть свои недостатки, о которых обычно люди не говорят. For-l oop облегчает использование кучи памяти и процессора. Если лучшая скорость процессора и куча является приоритетом, использование потоков обычно не рекомендуется.

Будучи новичком ie в программировании, я все же предпочел бы иметь декларативный стиль программирования без явного показа потока управления, и фактически он "работает"

На практике вам определенно разрешено изменять состояние экземпляра, но технически не источник источника. Вам не разрешено изменять источник данных во время выполнения функции потока javase8.stream

Так что, в основном, в качестве примера: Это хорошо: основано на вашем коде:

Arrays.stream(arr).forEach(x -> instance.modifyInstanceStateWithNum(x));

Но что-то вроде этого не так:

List<Pojo> pojos; //some pojo
pojos.stream().forEach(pojo-> pojos.remove(pojo)); //THIS ISN'T RIGHT

Подводя итог вашим сомнениям, это зависит от того, что вы делаете, правильно или нет, и от того, как вы считаете, код должен сосредоточиться больше на удобочитаемости кода, эффективности и тысячах строк кода, я честно предпочитаю lambda functions вместо generi c for-l oop, пока «это работает», и любой может легко понять, что я пытался сделать.

Это также совмещается в сочетании с FP-ориентированным программированием и выглядит так, как развиваются языки программирования, это уважается.

...