2012-02-14 4 views
5

java.util.LinkedHashSet을 리턴하는 메소드로 Java API에 대한 Clojure 인터페이스를 작성합니다.Java 콜렉션을 Clojure 데이터 구조로 변환

첫째, LinkedHashSet을 클로저 데이터 구조로 변환하기 위해이를 처리하는 관용적 인 Clojure 방법이 무엇입니까?

둘째, Java 콜렉션을 Clojure 데이터 구조로 변환하는 가장 좋은 방법은 무엇입니까?

답변

12

는 많은 옵션이 있습니다. Clojure에서 사용하려는 데이터 구조에 따라 달라집니다. 당신은 자바 라이브러리를 포장하고 깨끗한을 제시하려는 경우

  • : 여기

    은 몇 가지 예입니다 : 이들 각각을 사용하는 경우에 대해서는

    ;; create a HashSet 
    (def a (java.util.HashSet.)) 
    (dotimes [i 10] (.add a i)) 
    
    ;; Get all the values as a sequence 
    (seq a) 
    => (0 1 2 3 4 5 6 7 8 9) 
    
    ;; build a new HashSet containing the values from a 
    (into #{} a) 
    #{0 1 2 3 4 5 6 7 8 9} 
    
    ;; Just use the HashSet directly (high performance, no copy required) 
    (.contains a 1) 
    => true 
    (.contains a 100) 
    => false 
    

    , 나는 다음과 같은 조언을 건의 할 것 Clojure API를 사용하면 동일한 Clojure 데이터 구조로 변환하는 것이 좋습니다. 이것은 Clojure 사용자가 기대하는 것이며, 잠재적으로 지저분한 Java interop 세부 정보를 숨길 수 있습니다. 보너스로, 이것은 당신이 그들을 사용하는 동안 돌연변이 자바 컬렉션의 위험을 실행하지 않도록 것들을 불변하게 만들 것입니다.

  • Java API를 빠르고 효율적으로 사용하려면 자바 컬렉션에서 Java interop을 직접 사용하십시오.
2

자바 컬렉션을 클로저로 변환하는 관용적 인 방법은 시퀀스에서 작동하는 대부분의 함수에서 이미 호출 한 (seq) 함수를 사용하는 것입니다.

(def s (java.util.LinkedHashSet.)) 
#'user/s 
user> (seq s) 
nil 
user> (.add s "foo") 
true 
user> (seq s) 
("foo") 
user> 
2

나는 보편적으로 받아 들여 연습이 있는지 솔직히 잘 모르겠지만, 원래 자바 API와의 호환성을 깰 여기 Clojure의 어댑터에 자바에 대해 크리스 하우저 arguing을합니다.

당신이 요청한 변환을 수행하려면 into를 사용 Clojure의 자바 컬렉션과 매우 잘 재생하기 때문에

user=> (import java.util.LinkedHashSet) 
java.util.LinkedHashSet 
user=> (def x (LinkedHashSet.)) 
#'user/x 
user=> (.add x "test") 
true 
user=> (def y (into #{} x)) 
#'user/y 
user=> y 
#{"test"}