[list] Clojure에서 목록 위에 벡터를 사용해야하는 경우와 다른 방법은 무엇입니까?

Vectors는 seqs가 아니지만 Lists는 읽습니다. 하나를 사용하는 이유가 무엇인지 잘 모르겠습니다. 벡터가 가장 많이 사용되는 것 같지만 그 이유가 있습니까?



답변

다시 한 번, 나는 참을성이 없어서 Freenode의 #clojure에 질문하여 내 자신의 질문에 대답 한 것 같습니다. Stackoverflow.com에서 자신의 질문에 대답하는 것이 좋습니다. : D

나는 Rich Hickey와 빠른 토론을했으며 여기에 요점이 있습니다.

[12:21] <Raynes>    Vectors aren't seqs, right?
[12:21] <rhickey>   Raynes: no, but they are sequential
[12:21] <rhickey>   ,(sequential? [1 2 3])
[12:21] <clojurebot>    true
[12:22] <Raynes>    When would you want to use a list over a vector?
[12:22] <rhickey>   when generating code, when generating back-to-front
[12:23] <rhickey>   not too often in Clojure


답변

Java 프로그래밍을 많이 해왔고 Java 콜렉션 프레임 워크에 익숙한 경우와 같은 목록 LinkedList과 벡터를 생각하십시오 ArrayList. 따라서 컨테이너를 거의 같은 방식으로 선택할 수 있습니다.

더 명확하게 설명하려면 시퀀스의 앞이나 뒤에 개별 항목을 많이 추가하려는 경우 매번 항목을 뒤섞을 필요가 없으므로 연결된 목록이 벡터보다 훨씬 좋습니다. 그러나 특정 요소 (목록의 앞이나 근처가 아닌)에 자주 액세스하려면 (예 : 임의 액세스) 벡터를 사용하는 것이 좋습니다.

그런데 벡터를 쉽게 seq로 바꿀 수 있습니다.

user=> (def v (vector 1 2 3))
#'user/v
user=> v
[1 2 3]
user=> (seq v)
(1 2 3)
user=> (rseq v)
(3 2 1)


답변

벡터는 랜덤 액세스 시간이 O (1)이지만 사전 할당되어야합니다. 목록은 동적으로 확장 될 수 있지만 임의의 요소에 액세스하는 것은 O (n)입니다.


답변

벡터를 사용하는 경우 :

  • 인덱싱 된 액세스 성능-인덱싱 된 액세스에 대한 ~ O (1) 비용 vs. 목록에 대한 O (n)
  • 추가-conj 포함 ~ O (1)
  • 편리한 표기법-어느 쪽이든 작동하는 상황에서 리터럴 목록에 대해 ‘(1 2 3)보다 타이핑하고 읽는 것이 더 쉽다는 것을 알았습니다.

목록을 사용하는 경우 :

  • 시퀀스로 액세스하려는 경우 (목록은 새 객체를 할당하지 않고 seq를 직접 지원하므로)
  • 앞에-cons 또는 conj가있는 목록의 시작 부분에 추가하는 것은 O (1)입니다.

답변

간단한 참고 사항 :

"Vectors는 seqs가 아니지만 Lists는 읽습니다." 

시퀀스는 목록 또는 벡터 (또는 맵 또는 세트)보다 일반적입니다.
불행히도 REPL은 목록과 시퀀스를 동일하게 인쇄 한다는 것이 불행합니다 . 왜냐하면 목록이 다르더라도 실제로는 목록처럼 보이기 때문입니다. (seq) 함수는 목록을 포함하여 많은 다른 것들로부터 시퀀스를 만들고, seq를 사용하여 멋진 일을하는 수많은 함수 중 하나에 seq를 공급할 수 있습니다.

user> (class (list 1 2 3))
clojure.lang.PersistentList

user> (class (seq (list 1 2 3)))
clojure.lang.PersistentList

user> (class (seq [1 2 3]))
clojure.lang.PersistentVector$ChunkedSeq

Sec에는 이미 seq 인 경우 인수를 반환하는 바로 가기가 있습니다.

user> (let [alist (list 1 2 3)] (identical? alist (seq alist)))
true
user> (identical? (list 1 2 3) (seq (list 1 2 3)))
false

static public ISeq seq(Object coll){
        if(coll instanceof ASeq)
                return (ASeq) coll;
        else if(coll instanceof LazySeq)
                return ((LazySeq) coll).seq();
        else
                return seqFrom(coll);
}

리스트는 시퀀스이지만 다른 것들도 있지만 모든 시퀀스가리스트 인 것은 아닙니다.


답변