Interoperability Between Java and Vavr – Java和Vavr之间的互操作性

最后修改: 2018年 5月 16日

中文/混合/英文(键盘快捷键:t)

1. Overview

1.概述

As Vavr primarily works within the Java ecosystem, there’s always a need to convert Vavr’s data structures into Java-understandable data structures.

由于Vavr主要在Java生态系统中工作,因此总是需要将Vavr的数据结构转换为Java可理解的数据结构。

For example, consider a function which returns an io.vavr.collection.List, and we need to pass on the result to another function which accepts java.util.List. This is where the Java-Vavr interoperability comes in handy.

例如,考虑一个返回io.vavr.collection.List的函数,我们需要将结果传递给另一个接受java.util.List.的函数,这就是Java-Vavr互操作性发挥作用的地方。

In this tutorial, we’re going to look at how to convert several Vavr data structures into our standard Java collections and vice versa.

在本教程中,我们将研究如何将几个Vavr数据结构转换为我们的标准Java集合,反之亦然。

2. Vavr to Java Conversion

2.Vavr到Java的转换

The Value interface in Vavr is a base interface for most Vavr tools. Thus, all Vavr’s collections inherit the properties of Value.

Vavr中的Value接口是大多数Vavr工具的基础接口。因此,所有Vavr的集合都继承了Value.的属性。

This is useful as the Value interface comes with a lot of toJavaXXX() methods that allow us to convert the Vavr data structures to Java equivalents.

这很有用,因为Value接口带有很多toJavaXXX()方法,允许我们将Vavr数据结构转换成Java等价物。

Let’s see how a Java List can be obtained from the List or Stream of Vavr:

让我们看看如何从Vavr的ListStream中获得一个JavaList

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

The first example converts a Vavr list to a Java list, and the next one converts a stream to Java list. Both examples rely on the toJavaList() method.

第一个例子是将Vavr列表转换为Java列表,下一个例子是将一个流转换为Java列表。这两个例子都依赖于toJavaList()方法。

Similarly, we can obtain other Java collections from Vavr objects.

同样,我们可以从Vavr对象中获得其他Java集合

Let’s see another example of converting a Vavr Map to a Java Map:

让我们看看另一个将Vavr Map转换为Java Map的例子:

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

Besides standard Java collections, Vavr also provides APIs for converting values to Java streams and Optionals.

除了标准的Java集合,Vavr还提供了将值转换为Java流和Optionals的API。

Let’s see an example of obtaining an Optional using the toJavaOptional() method:

让我们看一个使用toJavaOptional()方法获得Optional的例子。

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

As an overview of the Vavr methods of this type, we have:

作为对这种类型的Vavr方法的概述,我们有。

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

A full list of useful APIs can be found here.

有用的API的完整列表可以在这里找到。

3. Java to Vavr Conversion

3.Java到Vavr的转换

All the collection implementations in Vavr have a base type of Traversable. Thus, each collection type features a static method ofAll() that takes an Iterable and converts it to the corresponding Vavr collection.

Vavr中所有的集合实现都有一个Traversable的基础类型。每个集合类型都有一个静态方法ofAll(),它接收一个Iterable并将其转换为相应的Vavr集合。

Let’s see how we can convert a java.util.List to a Vavr List:

让我们看看如何将java.util.List转换为Vavr List

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

Similarly, we can use the ofAll() method to convert Java streams to Vavr collections:

同样,我们可以使用ofAll()方法来将Java流转换为Vavr集合。

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

4. Java Collection Views

4.Java集合视图

The Vavr library also provides Java collection views which delegate calls to the underlying Vavr collections.

Vavr库还提供了Java集合视图,它委托调用底层的Vavr集合

The Vavr to Java conversion methods creates a new instance by iterating through all elements to build a Java collection. This means the performance of the conversion is linear, whereas the performance of creating collection views is constant.

Vavr到Java的转换方法通过迭代所有元素来创建一个新的实例,以建立一个Java集合。这意味着转换的性能是线性的,而创建集合视图的性能是不变的。

As of writing this article, only the List view is supported in Vavr.

截至本文写作时,Vavr中只支持List视图。

For the List, there are two methods that are available to get our View. First is asJava() which returns an immutable List and the next one is asJavaMutable().

对于List,有两个方法可用于获取我们的View。第一个是asJava() ,它返回一个不可变的List ,另一个是asJavaMutable()

Here’s an example that demonstrates the immutable Java List:

这里有一个例子,演示了不可变的Java List

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

As the List is immutable performing any modification on it throws an UnsupportedOperationException.

由于List是不可变的,对其进行任何修改都会抛出UnsupportedOperationException

We can also get a mutable List by invoking the asJavaMutable() method on List.

我们还可以通过对List.调用asJavaMutable()方法来获得一个可变的List

Here’s how we do it:

我们是这样做的。

@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. Conversion Between Vavr Objects

5.Vavr对象之间的转换

Similar to conversion between Java to Vavr and vice-versa, we can convert a Value type in Vavr to other Value types. This conversion feature helps conversion between the Vavr objects when there is a need.

类似于Java与Vavr之间的转换,反之亦然,我们可以将Vavr中的Value类型转换成其他Value类型。当有需要时,这种转换功能有助于Vavr对象之间的转换。

For example, we have a List of items, and we want to filter the duplicates while preserving the order. In this case, we would need a LinkedHashSet. Here’s an example that demonstrates the use case:

例如,我们有一个List项,我们想在保留顺序的同时过滤重复的项。在这种情况下,我们需要一个LinkedHashSet。下面是一个演示该用例的例子。

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

There are many other methods available in the Value interface which help us to convert collections to different types depending on the use cases.

在Value接口中还有许多其他的方法,它们可以帮助我们根据使用情况将集合转换为不同的类型。

A full list of the APIs can be found here.

API的完整清单可以在这里找到。

6. Conclusion

6.结论

In this article, we’ve learned about conversion between Vavr and Java collection types. To check out more APIs provided for conversion by the framework as per the use case, refer to the JavaDoc and the user guide.

在这篇文章中,我们已经了解了Vavr和Java集合类型之间的转换。要查看框架根据使用情况提供的更多转换API,请参考JavaDoc用户指南

The complete source code for all the examples in this article can be found over on Github.

本文中所有例子的完整源代码可以在Github上找到over