JavaConverters และ JavaConversions ใน Scala แตกต่างกันอย่างไร


197

ในscala.collectionมีสองวัตถุที่คล้ายกันมากและJavaConversionsJavaConverters

  • ความแตกต่างระหว่างวัตถุทั้งสองนี้คืออะไร?
  • ทำไมพวกเขาทั้งสองอยู่?
  • เมื่อใดที่ฉันต้องการใช้หนึ่งกับอื่น ๆ

คำตอบ:


253

แก้ไข: Java Conversionsได้@deprecatedใน Scala 2.13.0 ใช้scala.jdk.CollectionConvertersแทน

JavaConversionsจัดเตรียมชุดของวิธีการโดยนัยที่แปลงระหว่างคอลเลกชัน Java และคอลเลกชันสกาล่าที่เกี่ยวข้องที่ใกล้เคียงที่สุดและในทางกลับกัน สิ่งนี้ทำได้โดยการสร้าง wrappers ที่ใช้อินเทอร์เฟซ Scala และส่งต่อการเรียกไปยังคอลเลกชัน Java พื้นฐานหรืออินเทอร์เฟซ Java การโอนสายไปยังคอลเลกชัน Scala

JavaConvertersใช้รูปแบบ pimp-my-library เพื่อ“ เพิ่ม” asScalaวิธีการไปยังคอลเลกชัน Java และasJavaวิธีการในคอลเลกชัน Scala ซึ่งกลับ wrapper ที่เหมาะสมกล่าวถึงข้างต้น มันใหม่กว่า (ตั้งแต่รุ่น 2.8.1) มากกว่าJavaConversions(ตั้งแต่ 2.8) และทำให้การแปลงระหว่างคอลเลกชัน Scala และ Java ชัดเจน ตรงกันข้ามกับสิ่งที่ดาวิดเขียนไว้ในคำตอบของเขาฉันขอแนะนำให้คุณใช้เป็นนิสัยในการใช้JavaConvertersเพราะคุณจะมีโอกาสน้อยที่จะเขียนโค้ดที่ทำให้เกิดการแปลงโดยนัยมากเนื่องจากคุณสามารถควบคุมเฉพาะจุดที่จะเกิดขึ้น : ที่คุณเขียนหรือ.asScala.asJava

นี่คือวิธีการแปลงที่JavaConvertersให้:

Pimped Type                            | Conversion Method   | Returned Type
=================================================================================================
scala.collection.Iterator              | asJava              | java.util.Iterator
scala.collection.Iterator              | asJavaEnumeration   | java.util.Enumeration
scala.collection.Iterable              | asJava              | java.lang.Iterable
scala.collection.Iterable              | asJavaCollection    | java.util.Collection
scala.collection.mutable.Buffer        | asJava              | java.util.List
scala.collection.mutable.Seq           | asJava              | java.util.List
scala.collection.Seq                   | asJava              | java.util.List
scala.collection.mutable.Set           | asJava              | java.util.Set
scala.collection.Set                   | asJava              | java.util.Set
scala.collection.mutable.Map           | asJava              | java.util.Map
scala.collection.Map                   | asJava              | java.util.Map
scala.collection.mutable.Map           | asJavaDictionary    | java.util.Dictionary
scala.collection.mutable.ConcurrentMap | asJavaConcurrentMap | java.util.concurrent.ConcurrentMap
—————————————————————————————————————————————————————————————————————————————————————————————————
java.util.Iterator                     | asScala             | scala.collection.Iterator
java.util.Enumeration                  | asScala             | scala.collection.Iterator
java.lang.Iterable                     | asScala             | scala.collection.Iterable
java.util.Collection                   | asScala             | scala.collection.Iterable
java.util.List                         | asScala             | scala.collection.mutable.Buffer
java.util.Set                          | asScala             | scala.collection.mutable.Set
java.util.Map                          | asScala             | scala.collection.mutable.Map
java.util.concurrent.ConcurrentMap     | asScala             | scala.collection.mutable.ConcurrentMap
java.util.Dictionary                   | asScala             | scala.collection.mutable.Map
java.util.Properties                   | asScala             | scala.collection.mutable.Map[String, String]

หากต้องการใช้การแปลงโดยตรงจาก Java คุณจะดีกว่าวิธีการโทรJavaConversionsโดยตรง เช่น:

List<String> javaList = new ArrayList<String>(Arrays.asList("a", "b", "c"));
System.out.println(javaList); // [a, b, c]
Buffer<String> scalaBuffer = JavaConversions.asScalaBuffer(javaList);
System.out.println(scalaBuffer); // Buffer(a, b, c)
List<String> javaListAgain = JavaConversions.bufferAsJavaList(scalaBuffer);
System.out.println(javaList == javaListAgain); // true

5
ใช่ใช้ JavaConverters มากกว่า JavaConversions แต่ให้พิจารณาใช้github.com/scalaj/scalaj-collectionเนื่องจากมีประโยชน์บางประการเช่นการแปลง java.util.List เป็น Seq (เป็นรายการข้างต้นจาก 2.8.1?)
oluies

7
@ David ในขณะที่การแปลงโดยนัยเช่นที่จัดทำโดยJavaConversionsสะดวกคุณอาจมองข้ามสถานที่ทั้งหมดที่คอมไพเลอร์สามารถแทรกได้ JavaConvertersคุณสามารถควบคุมสถานที่เหล่านั้นด้วย เป็นการสนทนาทั้งหมดเกี่ยวกับการแปลงโดยนัยกับการแปลงที่ชัดเจน
Jean-Philippe Pellet

1
@ Jean-PhilippePellet การแปลงโดยนัยใน Scala นั้นขึ้นอยู่กับขอบเขตดังนั้นหากคุณไม่ทำเช่นimport JavaConversions._นั้นการแปลงจะไม่เกิดขึ้นดังนั้นคุณจึงสามารถควบคุมสิ่งที่ถูกแปลงได้ หากคุณวางการนำเข้าอย่างถูกต้อง (เมื่อจำเป็น) คุณจะสามารถควบคุมได้อย่างเต็มที่ว่าการแปลงเสร็จสิ้นที่ใด
David

2
@ David ... และเมื่อJavaConvertersคุณมีความปลอดภัยเพิ่มเติมที่ไม่มีอะไรเกิดขึ้นนอกเสียจากคุณจะเขียนไว้อย่างชัดเจน นั่นคือการรักษาความปลอดภัยเพิ่มเติมและนั่นอาจเป็นสาเหตุที่ทำให้คลาสนี้ถูกเพิ่มเข้ามา
Jean-Philippe Pellet

23
คุณคิดว่าการตั้งชื่อจะดีกว่า: เช่น "JavaConversionsImplicit" และ "JavaConversionsExplicit" จะแยกแยะได้ง่ายขึ้น
รามัน

52

สำหรับผู้ที่เชื่อมโยงไปถึงคำถามนี้ตั้งแต่ Scala 2.12.x JavaConversionsตอนนี้เลิกใช้แล้วและJavaConvertersเป็นวิธีที่ต้องการ


2
ตั้งแต่ Scala 2.13 JavaConvertersเลิกใช้แล้วและscala.jdk.CollectionConvertersเป็นวิธีที่ต้องการ;)
antonone

4

ในกาลา 2.13 JavaConvertersได้รับการเลิกในความโปรดปรานของscala.jdk.CollectionConverters :

แพคเกจใหม่ ... scala.jdkกับวัตถุCollectionConverters (คอลเลกชัน Java คลาสสิกคล้ายกับcollection.JavaConvertersใน 2.12) StreamConverters, FunctionConvertersและOptionConverters...


3

ดังที่อธิบายไว้ใน API JavaConversionsคือชุดของการแปลงโดยนัยที่เปลี่ยนคอลเล็กชัน Java เป็นคอลเลกชันสกาล่าที่เกี่ยวข้อง

import collection.JavaConversions._คุณสามารถใช้มันด้วย เมื่อจำเป็นผู้แปลจะแปลงชุดภาษาจาวาให้เป็นประเภทสกาล่าที่ถูกต้องโดยอัตโนมัติ

JavaConvertersเป็นชุดมัณฑนากรที่ช่วยแปลงคอลเลกชัน java หรือสกาล่าเป็นคอลเลกชันสกาล่าหรือ java โดยใช้asScalaหรือasJavaวิธีการที่จะถูกเพิ่มเข้าไปในคอลเลกชันที่คุณต้องการแปลงโดยปริยาย ในการใช้ตัวแปลงเหล่านี้คุณต้องนำเข้า:

import collection.JavaConverters._

คุณควรจะชอบJavaConversionsเพราะมันใช้งานง่ายกว่า (ไม่จำเป็นต้องใช้asScalaหรือasJava)


15
ในขณะที่ใช้วิธีการโดยนัยโดยสิ้นเชิงของ JavaConverters นั้นเขียนได้ง่ายกว่า แต่ก็ยากที่จะอ่าน รูปแบบสกาล่าปัจจุบันแสดงให้เห็นว่าเป็นการดีกว่าที่จะเรียกวิธีการอย่างชัดเจนเพื่อทำการแปลง
Leif Wickland

JavaConversions เลิกใช้แล้วใน Scala 2.12
Andrzej Wąsowski
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.