Tôi sẽ mở rộng nhận xét của mình một chút. Các List[T]
cấu trúc dữ liệu, từ scala.collection.immutable
được tối ưu hóa để làm việc theo cách một danh sách bất biến trong một hoàn toàn chức năng hơn công trình ngôn ngữ lập trình. Nó đã rất nhanh thêm vào trước lần, và người ta cho rằng bạn sẽ làm việc trên đầu cho hầu hết các truy cập của bạn.
Danh sách không thay đổi có được thời gian trả trước rất nhanh do thực tế là họ mô hình hóa danh sách được liên kết của họ dưới dạng một loạt các "tế bào khuyết điểm". Ô xác định một giá trị đơn và một con trỏ tới ô tiếp theo (kiểu danh sách liên kết đơn lẻ cổ điển):
Cell [Value| -> Nil]
Khi bạn thêm vào một danh sách, bạn thực sự chỉ tạo một ô mới, phần còn lại của danh sách hiện tại được trỏ đến:
Cell [NewValue| -> [Cell[Value| -> Nil]]
Bởi vì danh sách này là bất biến, bạn an toàn để làm điều này mà không cần sao chép thực tế . Không có nguy cơ danh sách cũ thay đổi và khiến tất cả các giá trị trong danh sách mới của bạn trở nên không hợp lệ. Tuy nhiên, bạn mất khả năng có một con trỏ có thể thay đổi đến cuối danh sách của bạn như một sự thỏa hiệp.
Điều này cho vay rất tốt để làm việc đệ quy trên danh sách. Giả sử bạn đã xác định phiên bản của riêng mình filter
:
def deleteIf[T](list : List[T])(f : T => Boolean): List[T] = list match {
case Nil => Nil
case (x::xs) => f(x) match {
case true => deleteIf(xs)(f)
case false => x :: deleteIf(xs)(f)
}
}
Đó là một hàm đệ quy chỉ hoạt động từ phần đầu của danh sách và tận dụng lợi thế của khớp mẫu thông qua trình trích xuất ::. Đây là thứ bạn thấy rất nhiều trong các ngôn ngữ như Haskell.
Nếu bạn thực sự muốn nối nhanh, Scala cung cấp rất nhiều cấu trúc dữ liệu có thể thay đổi và bất biến để lựa chọn. Về phía đột biến, bạn có thể nhìn vào ListBuffer
. Ngoài ra, Vector
từ scala.collection.immutable
có một thời gian nối nhanh.