«1. Обзор

Поскольку Vavr в основном работает в экосистеме Java, всегда необходимо преобразовать структуры данных Vavr в понятные для Java структуры данных.

Например, рассмотрим функцию, которая возвращает io.vavr.collection.List, и нам нужно передать результат другой функции, которая принимает java.util.List. Вот где на помощь приходит совместимость Java-Vavr.

В этом уроке мы рассмотрим, как преобразовать несколько структур данных Vavr в наши стандартные коллекции Java и наоборот.

2. Преобразование Vavr в Java

Интерфейс Value в Vavr является базовым интерфейсом для большинства инструментов Vavr. Таким образом, все коллекции Vavr наследуют свойства Value.

Это полезно, так как интерфейс Value содержит множество методов toJavaXXX(), которые позволяют нам преобразовывать структуры данных Vavr в эквиваленты Java.

Давайте посмотрим, как можно получить список Java из списка или потока Vavr:

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

В первом примере список Vavr преобразуется в список Java, а в следующем — поток преобразуется в Java. список. Оба примера основаны на методе toJavaList().

Точно так же мы можем получить другие коллекции Java из объектов Vavr.

Map<String, String> vavrMap = HashMap.of("1", "a", "2", "b", "3", "c");
java.util.Map<String, String> javaMap = vavrMap.toJavaMap();

Давайте рассмотрим еще один пример преобразования карты Vavr в карту Java:

Помимо стандартных коллекций Java, Vavr также предоставляет API для преобразования значений в потоки Java и дополнительные параметры.

List<String> vavrList = List.of("Java");
Optional<String> optional = vavrList.toJavaOptional();
assertEquals("Java", optional.get());

Давайте рассмотрим пример получения Optional с помощью метода toJavaOptional():

    В качестве обзора методов Vavr этого типа мы имеем:

toJavaArray() toJavaCollection() toJavaList() toJavaMap() toJavaSet() toJavaOptional() toJavaParallelStream() toJavaStream()

Полный список полезных API можно найти здесь.

3. Преобразование Java в Vavr

Все реализации коллекций в Vavr имеют базовый тип Traversable. Таким образом, каждый тип коллекции имеет статический метод All(), который принимает Iterable и преобразует его в соответствующую коллекцию Vavr.

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

Давайте посмотрим, как мы можем преобразовать java.util.List в список Vavr:

java.util.stream.Stream<String> javaStream 
  = Arrays.asList("Java", "Haskell", "Scala").stream();
Stream<String> vavrStream = Stream.ofAll(javaStream);

Точно так же мы можем использовать метод ofAll() для преобразования потоков Java в коллекции Vavr:

4. Представления коллекций Java

Библиотека Vavr также предоставляет представления коллекций Java, которые делегируют вызовы базовым коллекциям Vavr.

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

На момент написания этой статьи в Vavr поддерживается только представление списка.

Для списка доступны два метода получения представления. Первый — это asJava(), который возвращает неизменяемый список, а следующий — asJavaMutable().

@Test(expected = UnsupportedOperationException.class)
public void givenParams_whenVavrListConverted_thenException() {
    java.util.List<String> javaList 
      = List.of("Java", "Haskell", "Scala").asJava();
    
    javaList.add("Python");
    assertEquals(4, javaList.size());
}

Вот пример, демонстрирующий неизменяемый список Java:

Поскольку список является неизменяемым, любое изменение в нем вызывает исключение UnsupportedOperationException.

Мы также можем получить изменяемый список, вызвав метод asJavaMutable() для списка.

@Test
public void givenParams_whenVavrListConvertedToMutable_thenRetunMutableList() {
    java.util.List<String> javaList = List.of("Java", "Haskell", "Scala")
      .asJavaMutable();
    javaList.add("Python");
 
    assertEquals(4, javaList.size());
}

Вот как мы это делаем:

5. Преобразование между объектами Vavr

Подобно преобразованию между Java в Vavr и наоборот, мы можем преобразовать тип Value в Vavr в другие типы Value. Эта функция преобразования помогает преобразованию между объектами Vavr, когда это необходимо.

List<String> vavrList = List.of("Java", "Haskell", "Scala", "Java");
Set<String> linkedSet = vavrList.toLinkedSet();
assertEquals(3, linkedSet.size());
assertTrue(linkedSet instanceof LinkedHashSet);

Например, у нас есть список элементов, и мы хотим отфильтровать дубликаты, сохраняя порядок. В этом случае нам понадобится LinkedHashSet. Вот пример, демонстрирующий вариант использования:

В интерфейсе Value доступно множество других методов, которые помогают нам преобразовывать коллекции в разные типы в зависимости от вариантов использования.

Полный список API можно найти здесь.

6. Заключение

В этой статье мы узнали о преобразовании между типами коллекций Vavr и Java. Чтобы ознакомиться с дополнительными API-интерфейсами, предоставляемыми платформой для преобразования в соответствии с вариантом использования, обратитесь к JavaDoc и руководству пользователя.