Команда Java здійснила велику роботу, усуваючи бар'єри для функціонального програмування на Java 8. Зокрема, зміни в колекціях java.util виконують велику роботу з ланцюжка перетворень на дуже швидкі потокові операції. Зважаючи на те, наскільки добре вони виконали додавання першокласних функцій та функціональних методів у колекції, чому вони повністю не змогли надати незмінних колекцій чи навіть незмінних інтерфейсів колекції?
Не змінюючи жодного існуючого коду, команда Java могла б у будь-який час додати незмінних інтерфейсів, таких самих, як і ті, що змінюються, за вирахуванням методів "встановити" та змусити існуючі інтерфейси поширюватися з них, як це:
ImmutableIterable
____________/ |
/ |
Iterable ImmutableCollection
| _______/ / \ \___________
| / / \ \
Collection ImmutableList ImmutableSet ImmutableMap ...
\ \ \_________|______________|__________ |
\ \___________|____________ | \ |
\___________ | \ | \ |
List Set Map ...
Зрозуміло, такі операції, як List.add () та Map.put (), в даний час повертають булеве або попереднє значення для даного ключа, щоб вказати, чи вдалася операція чи не вдалася. Незмінні колекції повинні були б розглядати такі методи як фабрики та повертати нову колекцію, що містить доданий елемент - що несумісне з поточним підписом. Але це можна вирішити, використовуючи іншу назву методу, як ImmutableList.append () або .addAt () та ImmutableMap.putEntry (). Отримане багатослів’я було б більш ніж переважене на користь роботи з незмінними колекціями, а система типів запобігла б помилкам викликати неправильний метод. З часом старі методи можуть бути застарілими.
Виграші незмінних колекцій:
- Простота - міркування про код простіше, коли основні дані не змінюються.
- Документація - якщо метод приймає незмінний інтерфейс колекції, ви знаєте, що він не збирається змінювати цю колекцію. Якщо метод повертає незмінну колекцію, ви знаєте, що ви не можете її змінити.
- Паралельність - незмінні колекції можна безпечно ділити по нитках.
Як хтось, хто скуштував мови, які передбачають незмінність, повернутися на Дикий Захід бурхливих мутацій дуже важко. У колекціях Clojure (абстракція послідовностей) вже є все, що надають колекції Java 8, плюс незмінність (хоча можливо використання додаткової пам’яті та часу завдяки синхронізованим спискам зв’язків замість потоків). Scala має як змінні, так і незмінні колекції з повним набором операцій, і хоча ці операції прагнуть, виклик .iterator надає лінивий погляд (і є інші способи ліниво оцінити їх). Я не бачу, як Java може продовжувати конкурувати без незмінних колекцій.
Чи може хтось вказати мені на історію чи дискусію з цього приводу? Звичайно, це десь публічно.
const
колекції
Collections.unmodifiable*()
для чого. але не ставтесь до них як до незмінних, коли їх немає
ImmutableList
у цій діаграмі, люди можуть передавати змінні List
? Ні, це дуже погане порушення LSP.