在 Clojure 中使用 Java 流

2022-09-04 07:20:34

Java 8带来了Stream接口,以及它对Java集合(以及其他可以变成流的东西)的方便的map/filter/reduce操作。

我发现从Clojure使用流很尴尬和冗长,当与产生它们的Java API进行互操作时。

比较 – Java:

Pattern.compile("\\s+").splitAsStream("one two three")
        .filter(s -> !s.contains("o"))
        .map(String::toUpperCase)
        .findFirst()
        .orElse(null);  // => "THREE"

Clojure,尝试使用相同的 API:

(.. (.splitAsStream #"\s+" "one two three")
    (filter
      (reify java.util.function.Predicate
        (test [this value] (not (.contains value "o")))))
    (map
      (reify java.util.function.Function
        (apply [this value] (.toUpperCase value))))
    (findFirst)
    (orElse nil))  ; => "THREE"

有没有更好的方法来在Clojure中使用基于流的Java API?是否可以将流转换为 seq 并使用 Clojure 自己的转换函数,如 、 、 ?removepartitiontake


答案 1

您可以使用其迭代器()方法从流中获取java.util.Iterator。这可以使用迭代器-seq创建一个clojure序列:

(-> stream
    .iterator
    iterator-seq)

答案 2

推荐