Перейти к основному содержимому

Взаимодействие между Java и Vavr

· 4 мин. чтения

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 .

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

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

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

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

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

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

  • toJavaArray()
  • toJavaCollection()
  • toJavaList()
  • toJavaMap()
  • toJavaSet()
  • toJavaНеобязательный()
  • toJavaParallelStream()
  • toJavaStream()

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

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

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

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

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

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

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

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

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

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

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

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

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

@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());
}

Поскольку список неизменяем, выполнение любых изменений в нем вызывает исключение 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, когда это необходимо.

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

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

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

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

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

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

Полный исходный код всех примеров в этой статье можно найти на Github .