2014-05-23 11 views
5

Tôi muốn chuyển đổi một danh sách Java của Java double (java.util.List [java.lang.Double]) thành một danh sách Scala của Scala double (List [Double]) một cách hiệu quả.Làm thế nào để chuyển đổi java.util.List [java.lang.Double] thành Scala's List [Double]?

Hiện tại tôi đang lập bản đồ trong danh sách chuyển đổi từng giá trị Double thành Scala Double. Tôi không muốn bản đồ trên mọi giá trị và đang tìm kiếm một cách hiệu quả hơn để làm điều này.

import collection.JavaConversions._ 
import collection.mutable.Buffer 

val j: java.util.List[java.lang.Double] = Buffer(new java.lang.Double(1.0), new java.lang.Double(2.0)) 
val s: List[Double] = ... 

Tôi đã xem tài liệu để chuyển từ Scala -> Java, nhưng không nhiều theo cách khác.

+0

"Tôi đã xem tài liệu để chuyển từ Scala -> Java, nhưng không nhiều theo cách khác." ... bạn đã làm phải không? Chăm sóc để chia sẻ thông tin đó? ;-) – Make42

+0

Tôi phát hiện ra câu trả lời: https://stackoverflow.com/q/46830217/4533188 – Make42

Trả lời

14

Khuyến cáo là sử dụng JavaConverters, không JavaConversions:

import collection.JavaConverters._ 
import scala.collection.breakOut 
val l: List[Double] = j.asScala.map(_.doubleValue)(breakOut) 

doubleValue sẽ chuyển đổi nó từ một java.lang.Double thành một scala.Double. breakOut yêu cầu sản xuất List là kết quả của map, mà không cần phải đi qua thời gian khác để chuyển đổi thành List. Bạn cũng có thể chỉ cần toList thay vì breakOut nếu bạn không quan tâm đến việc truyền tải phụ.

Các lớp Java là các đối tượng hoàn toàn khác với các đối tượng Scala; nó không chỉ là một thay đổi tên. Vì vậy, nó sẽ không thể chuyển đổi mà không đi qua. Bạn phải tạo một bộ sưu tập hoàn toàn mới và sau đó xem từng phần tử để (chuyển đổi nó và) di chuyển nó qua.

Lý do các loại khác nhau là java.lang.Double là một "nguyên thủy đóng hộp" trong khi scala.Double tương đương với nguyên thủy đôi của Java. Chuyển đổi ở đây về bản chất là "unboxing" nguyên thủy.

+0

Có cách nào để thực hiện điều đó mà không có bất kỳ sự di chuyển nào không? Có lẽ điều đó là không thể, nhưng tôi ngây thơ tưởng tượng rằng việc đúc sẽ không liên quan đến bất kỳ cuộc tấn công nào. –

+0

Lưu ý rằng nếu bạn sẵn sàng chấp nhận 'Seq' thay vì' Danh sách' chính xác, bạn có thể tránh việc truyền tải bằng cách chuyển đổi danh sách Java được chuyển đổi thành Scala thành một khung nhìn bằng cách gọi phương thức 'view' trước khi gọi' map '. Điều đó sẽ cung cấp cho bạn một đánh giá lười biếng 'SeqView' sẽ áp dụng các chuyển đổi cho các yếu tố trên cơ sở khi cần thiết. – reggert

0
import collection.JavaConverters._ 

val javaList : java.util.List[Double] = ... 
val scalaList : List[Double] = j.asScala.toList 
+0

Điều này có thể truyền một java.util.list [Double] vào một Danh sách [Double], nhưng phần phức tạp là cũng chuyển đổi từ java.lang.Double thành Scala Double. –

+1

@Erik, Nó không phải là một diễn viên: 'asScala' đi qua bộ sưu tập dựa trên java và xây dựng bộ sưu tập dựa trên scala mới. Nó phải kể từ khi các lớp học hoàn toàn khác nhau. – dhg

+0

@ dhg, bạn đang thực sự sai. 'asScala' không đi qua một bộ sưu tập; 'asScala' tạo một khung nhìn * * vào bộ sưu tập gốc. Đó là 'toList' thực hiện truyền tải thực tế. Xem đặc điểm 'scala.collection.convert.Wrappers': nó chứa các triển khai của các khung nhìn này, và rõ ràng là chúng chỉ chuyển tiếp các hoạt động thu thập tới các bộ sưu tập Java ban đầu. –

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