Chuyển đổi bộ sưu tập Java thành bộ sưu tập Scala


88

Liên quan đến câu hỏi Stack Overflow Scala tương đương với HashSet (Bộ sưu tập) mới , làm cách nào để chuyển đổi bộ sưu tập Java ( java.util.Listgiả sử) thành bộ sưu tập Scala List?

Tôi thực sự đang cố gắng chuyển đổi một lệnh gọi Java API thành Spring's SimpleJdbcTemplate , nó trả về a java.util.List<T>, thành bất biến Scala HashSet. Ví dụ:

val l: java.util.List[String] = javaApi.query( ... )
val s: HashSet[String] = //make a set from l

Điều này có vẻ hiệu quả. Phê bình được hoan nghênh!

import scala.collection.immutable.Set
import scala.collection.jcl.Buffer 
val s: scala.collection.Set[String] =
                      Set(Buffer(javaApi.query( ... ) ) : _ *)

Câu trả lời:


17

Đề xuất cuối cùng của bạn hoạt động, nhưng bạn cũng có thể tránh sử dụng jcl.Buffer:

Set(javaApi.query(...).toArray: _*)

Lưu ý rằng scala.collection.immutable.Setđược cung cấp theo mặc định nhờ Predef.scala.


9
Đề nghị này không hoạt động mà tôi muốn giữ lại những thông tin kiểu
oxbow_lakes

127

Để tham khảo trong tương lai: Với Scala 2.8, nó có thể được thực hiện như sau:

import scala.collection.JavaConversions._
val list = new java.util.ArrayList[String]()
list.add("test")
val set = list.toSet

setlà một scala.collection.immutable.Set[String]sau này.

Ngoài ra, hãy xem câu trả lời của Ben James để biết một cách rõ ràng hơn (sử dụng JavaConverters), cách này dường như được khuyến nghị ngay bây giờ.


Có vẻ như bây giờ JavaConversionscó một số lý do khiến toSetcuộc gọi không cần thiết.
Rajish

@Rajish Tôi nghĩ rằng nó tốt hơn nếu việc chuyển đổi là rõ ràng (xem stackoverflow.com/questions/8301947/... )
krookedking

bạn nói đúng, tốt hơn hết là sử dụng import scala.collection.JavaConverters._
Abhishek Sengupta,

62

Nếu bạn muốn rõ ràng hơn JavaConversions được trình bày trong câu trả lời của robinst , bạn có thể sử dụng JavaConverters:

import scala.collection.JavaConverters._
val l = new java.util.ArrayList[java.lang.String]
val s = l.asScala.toSet

25

JavaConversions ( câu trả lời của robinst ) và JavaConverters ( câu trả lời của Ben James ) đã không được chấp nhận với Scala 2.10 .

Thay vì sử dụng JavaConversions :

import scala.collection.convert.wrapAll._

theo đề xuất của aleksandr_hramcov .

Thay vì sử dụng JavaConverters :

import scala.collection.convert.decorateAll._

Đối với cả hai, cũng có khả năng chỉ nhập các chuyển đổi / chuyển đổi sang Java hoặc Scala tương ứng, ví dụ:

import scala.collection.convert.wrapAsScala._

Cập nhật: Tuyên bố ở trên rằng JavaConversionsJavaConverters không được dùng nữa có vẻ là sai. Có một số thuộc tính không được dùng nữa trong Scala 2.10, dẫn đến cảnh báo không dùng nữa khi nhập chúng. Vì vậy, các nhập khẩu thay thế ở đây dường như chỉ là bí danh. Mặc dù tôi vẫn thích chúng hơn, vì IMHO những cái tên phù hợp hơn.


Tại sao bạn nói JavaConversions và JavaConverters không được dùng nữa? Trong tài liệu hiện tại 2.11.8, cả hai đều không được đánh dấu là không còn được dùng nữa và chúng cũng không có tham chiếu đến 'decorationAll' hoặc 'wrapAll' cho biết đó là cách sử dụng mới và được ưu tiên.
Joost den Boer,

@JoostdenBoer Có vẻ như có một số trình trang trí không được dùng nữa ở đó trong Scala 2.10, mặc dù chúng dường như đã bị xóa một lần nữa với Scala 2.11.
stempler

14

Bạn cũng có thể muốn khám phá thư viện tuyệt vời này: scalaj-collection có khả năng chuyển đổi hai chiều giữa các bộ sưu tập Java và Scala. Trong trường hợp của bạn, để chuyển đổi java.util.List sang Scala List, bạn có thể làm như sau:

val list = new java.util.ArrayList[java.lang.String]
list.add("A")
list.add("B")
list.asScala

1
Thư viện đó là điều tuyệt vời nhất từ ​​trước đến nay. Thực sự thực sự hoạt động tốt.
Michael Neale

6
Xem xét lại điều này sau vài năm, JavaConverters của Scala là cách để đi.
Surya Suravarapu

4

Bắt đầu Scala 2.13, gói scala.jdk.CollectionConvertersthay thế các gói scala.collection.JavaConverters/JavaConversions._:

import scala.jdk.CollectionConverters._

// val javaList: java.util.List[String] = java.util.Arrays.asList("one","two","three")
javaList.asScala
// collection.mutable.Buffer[String] = Buffer("one", "two", "three")
javaList.asScala.toSet
// collection.immutable.Set[String] = Set("one", "two", "three")

3
val array = java.util.Arrays.asList("one","two","three").toArray

val list = array.toList.map(_.asInstanceOf[String])

đây là một câu trả lời tuyệt vời và giải quyết được vấn đề của tôi. Hầu hết các phương pháp được đề cập trên internet chỉ chuyển đổi (ví dụ) java.util.List [java.lang.Long] thành scala.collection.immutable.List [java.lang.Long]. Vì vậy, phương pháp này đã hoạt động để tôi chuyển đổi nó thành scala.collection.immutable.List [scala.Long]
ajkl 21/12/14

2

Bạn có thể thêm thông tin kiểu trong lệnh gọi toArray để làm cho Tập hợp được tham số hóa:

 val s = Set(javaApi.query(....).toArray(new Array[String](0)) : _*)

Điều này có thể tốt hơn vì gói bộ sưu tập đang trải qua quá trình làm lại lớn cho Scala 2.8 và gói scala.collection.jcl sẽ biến mất


1

Bạn có thể chuyển đổi bộ sưu tập Java thành một mảng và sau đó tạo danh sách Scala từ đó:

val array = java.util.Arrays.asList("one","two","three").toArray
val list = List.fromArray(array)

2
Điều này không tuyệt vời vì java.util.List của tôi sắp trở lại API Java dưới dạng danh sách được tham số hóa (vì vậy lệnh gọi của tôi tới API tạo ra java.util.List <String>) - Tôi đang cố gắng biến điều này thành một scala HashSet bất biến
oxbow_lakes

1

Một cách đơn giản khác để giải quyết vấn đề này:

import collection.convert.wrapAll._
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.