Парадигма Java и функционального программирования - Как сделать мои массивы неизменными - PullRequest
3 голосов
/ 24 сентября 2019

Я пытаюсь создать код, который следует парадигме функционального программирования, которая очень неукоснительно следует неизменности, но единственный способ узнать, как сделать мой массив даже близким к неизменяемости, - это использовать

List<Integer> items = Collections.unmodifiableList(Arrays.asList(0,1,2,3));

Я не уверен, делает ли этот массив неизменным или просто неизменным.Если указанная выше команда не сделает массив неизменным, что будет?

Ответы [ 2 ]

2 голосов
/ 24 сентября 2019
  1. Вы не можете изменить базовый массив (или список, возвращаемый Arrays.asList), кроме как с помощью отражения.Однако массивы здесь не очень актуальны;не путайте массивы и списки!

  2. Начиная с Java 9, List.of(0, 1, 2, 3) достигает того же.

  3. Для выполнения операций, которые производят новые коллекциивам придется пройти через потоки .Вы также можете рассмотреть сторонние библиотеки, например, Guava (эта ссылка на страницу их неизменных коллекций) .Или даже лучше PCollections , который предоставляет только неизменяемые коллекции и более функциональные их реализации, чем Guava.

0 голосов
/ 25 сентября 2019

Проблема с использованием Collections.unmodifiableList заключается в том, что вы на самом деле не создаете представление только для чтения для изменяемой коллекции, а не реальную неизменяемую коллекцию.Может показаться, что это не имеет большого значения, но на самом деле изменяемая коллекция, действующая как неизменяемая, не будет очень эффективной и производительной.Например, добавление нового элемента в список потребует копирования всего списка.

Я бы посоветовал вам проверить Vavr .Он имеет собственную реализацию функционального, неизменного связанного списка , который позволяет выполнять добавления в постоянное время (что не требует копирования всего списка, поскольку общие элементы являются общими).Например:

var l1 = List.of(1, 2, 3); //List(1, 2, 3)
var l2 = l1.append(4);     //List(1, 2, 3, 4)

В этом примере оба списка будут разделены на 1,2,3.

Вы также можете легко конвертировать из и в список Java:

java.util.List<String> javaList = Arrays.asList("Java", "Haskell", "Scala");
List<String> vavrList = List.ofAll(javaList);

List<String> vavrStringList = List.of("JAVA", "Javascript", "Scala");
java.util.List<String> javaStringList = vavrStringList.toJavaList();
...