Does Common Lisp have a something like java's Set Interface/implementing classes?

前端 未结 8 1041
无人及你
无人及你 2021-01-12 01:58

I need something like this, a collection of elements which contains no duplicates of any element. Does Common Lisp, specifically SBCL, have any thing like this?

8条回答
  •  执念已碎
    2021-01-12 02:52

    You could use lists, though they can prove to be inefficient for representing large sets. This is done using ADJOIN or PUSHNEW to add a new element to a list, and DELETE or REMOVE to do the opposite.

    (let ((set (list)))
      (pushnew 11 set)
      (pushnew 42 set)
      (pushnew 11 set) 
      (print set) ; set={42,11}
      (setq set (delete 42 set))
      (print set)) ; set={11}
    

    One thing to watch out for is all that these operators use EQL by default to test for potential duplicates in the set (much as Java uses the equals method). That's OK for sets holding numbers or characters, but for sets of other objects, a `deeper' equality test such as EQUAL should be specified as a :TEST keyword parameter, e.g. for a set of strings :-

    (let ((set (list)))
      (pushnew "foo" set :test #'equal)
      (pushnew "bar" set :test #'equal)
      (pushnew "foo" set :test #'equal) ; EQUAL decides that "foo"="foo"
      (print set)) ; set={"bar","foo"}
    

    Lisp's counterparts to some of Java's Set operations are:

    • addAll -> UNION or NUNION
    • containsAll -> SUBSETP
    • removeAll -> SET-DIFFERENCE or NSET-DIFFERENCE
    • retainAll -> INTERSECTION or NINTERSECTION

提交回复
热议问题