2015-02-24 23 views
11

Trong khi làm việc thông qua việc chuyển đổi một số mã Java sang Scala, tôi đã phát hiện ra trong khi có phương thức contains cho Scala's Set, không có phương thức containsAll. Tôi chỉ thiếu tên phương pháp đúng không?Với Scala's Set, có phương pháp tương tự với phương thức containsAll trong Java Set không?

Dưới đây là một số mã tôi đã làm việc để lấp đầy khoảng trống để tôi có thể nhanh chóng quay lại làm việc. Là nó đủ, hoặc tôi thiếu một số tinh tế?

def containsAll[A](set: Set[A], subset: Set[A]): Boolean = 
    if (set.size >= subset.size) 
     subset.forall(a => set.contains(a)) 
    else 
     false 

Trả lời

17

subsetOf, mà kiểm tra có hay không các yếu tố của một Set được chứa trong Set khác. (Loại ngược lại về biểu thức)

val set = Set(1,2,3,4) 
val subset = Set(1,2) 

scala> subset.subsetOf(set) 
res0: Boolean = true 

scala> set.subsetOf(subset) 
res1: Boolean = false 
+0

Ah. Rất đẹp. Đó là một chút phản đối trong đó nó được đảo ngược từ Java. Nhưng nó chắc chắn làm những gì tôi cần. Tysvm cho phản ứng nhanh của bạn. – chaotic3quilibrium

5

Trong Scala, Set được trang bị với các hoạt động thiết lập như intersect, do đó ví dụ

set.intersect(subset) == subset 

truyền đạt ngữ nghĩa của containsAll, thậm chí là subsetOf như đã đề cập chứng minh ngắn gọn nhất.

+0

Điều này có thực sự kém hiệu quả hơn đối với các bộ có kích thước rất lớn (tưởng tượng hàng triệu mục nhập) không? IOW, bây giờ có hai hoạt động, thực hiện giao lộ và sau đó thực hiện kiểm tra tương đương. Có vẻ như một lần vượt qua thử nghiệm đầu tiên cho các phần tử trong tập thứ hai sẽ là ưu tiên hơn và hiệu quả hơn nhiều. – chaotic3quilibrium

3

Điều đáng nói là bạn có thể tạo các phương thức trợ giúp có nguồn gốc như containsAll sẵn có trên Set[T] nếu bạn muốn, bằng cách sử dụng lớp được làm giàu tiềm ẩn. Bạn cũng có thể xem xét thực hiện một tình trạng quá tải variadic:

implicit class RichSet[T](val x: Set[T]) extends AnyVal { 
    def containsAll(y: Set[T]): Boolean = y.subsetOf(x) 
    def containsAll(y: T*): Boolean = x.containsAll(y.toSet) 
} 

Vì vậy, sau đó bạn có thể làm:

Set(1, 2, 3).containsAll(Set(1, 2)) 

Hoặc:

Set(1, 2, 3).containsAll(1, 2) 
+0

Rất dễ thực hiện! Tôi chắc chắn sẽ thêm nó vào thư viện của tôi. – chaotic3quilibrium

+0

Lý do đằng sau sử dụng một cách rõ ràng 'mở rộng AnyVal' như trái ngược với việc bỏ qua điều đó được ngụ ý là gì? – chaotic3quilibrium

+3

Nó hiệu quả hơn. Từ các tài liệu: "... có thể định nghĩa một lớp con của AnyVal được gọi là lớp giá trị do người dùng định nghĩa được xử lý đặc biệt bởi trình biên dịch. Các lớp giá trị người dùng được định nghĩa đúng cách cung cấp một cách để cải thiện hiệu suất trên các kiểu do người dùng định nghĩa bởi tránh phân bổ đối tượng khi chạy, và bằng cách thay thế các lời gọi phương thức ảo bằng các lời gọi phương thức tĩnh. " Đọc thêm về các lớp giá trị 'AnyVal' và người dùng định nghĩa ở đây: http://www.scala-lang.org/api/2.11.4/index.html#scala.AnyVal –

Các vấn đề liên quan