在Clojure中使用Java流

glt*_*lts 11 java clojure java-8 java-stream

Java 8带来了Stream接口,并且可以方便地对Java集合(以及可以转换为流的其他东西)进行map/filter/reduce操作.

我发现在与生成它们的Java API进行互操作时,Clojure使用的流程很笨拙且冗长.

比较 - Java:

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

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"
Run Code Online (Sandbox Code Playgroud)

有没有更好的方法在Clojure中使用基于流的Java API?是否有可能把一个流转换为序列,并使用Clojure的自身转型的功能,如remove,partition,take

Mat*_*mer 25

您可以使用其iterator()方法从Stream中获取java.util.Iterator.可以使用iterator-seq创建一个clojure序列:

(-> stream
    .iterator
    iterator-seq)
Run Code Online (Sandbox Code Playgroud)