2016-04-08 15 views
5

Tôi có một lớp Scala Implicit từ API RecordService, mà tôi muốn sử dụng trong tệp Java.Cách sử dụng lớp ngầm Scala trong Java

package object spark { 

    implicit class RecordServiceContext(ctx: SparkContext) { 
    def recordServiceTextFile(path: String) : RDD[String] = { 
     new RecordServiceRDD(ctx).setPath(path) 
      .map(v => v(0).asInstanceOf[Text].toString) 
    } 
    } 

} 

Bây giờ tôi đang cố gắng để nhập khẩu này trong một file Java sử dụng dưới đây nhập khẩu.

import com.cloudera.recordservice.spark.*; 

Nhưng tôi không thể sử dụng recordServiceTextFile ("đường dẫn") từ sparkContext.

Trong Scala, việc nhập ít khác nhau và hoạt động của nó.

+1

Tôi không thấy một lớp ẩn. –

+0

Nhập mã Scala trong mã Java không phải là một hoạt động tầm thường đối với mắt tôi. Nó đòi hỏi một số hiểu biết về ruột javac. Ngoài ra câu hỏi không rõ ràng. Bạn có thể là một câu hỏi rõ ràng hơn hay không? Câu hỏi càng "đầy đủ" thì câu trả lời càng tốt. –

+0

@Ramesh Bạn được chào đón nhưng đó không phải là tôi. –

Trả lời

6

Dưới đây là định nghĩa đơn giản của lớp tiềm ẩn trong đối tượng gói

package object spark { 
    implicit class Ext(param: Int) { 
    def a = param + 1 
    } 
} 

và đây là cách bạn có thể sử dụng nó từ java

public class Test { 
    public static void main(String[] args) { 
     spark.package$.MODULE$.Ext(123).a(); 
    } 
} 

nên về cơ bản bạn có thể sử dụng RecordServiceContext như một phương pháp mà kết thúc tốt đẹp của bạn SparkContext và thêm phương thức bổ sung mà bạn có thể gọi. Đó là tối ưu hóa cho các lớp ngầm định.

Đó sẽ là một cái gì đó như thế này:

SparkContext c = ??? 
RDD<String> rdd = com.cloudera.recordservice.spark.package$.MODULE$.RecordServiceContext(c) 
    .recordServiceTextFile("asdf"); 
+0

Cảm ơn, hoạt động tốt .. – Shankar

0
SparkContext ctx = ... 
RecordServiceContext rsct = new RecordServiceContext(ctx) 
recordServiceTextFile("/your_path") 
0

Điều này sẽ thực hiện.

String s = new spark.RecordServiceContext("safa").recordServiceTextFile("dsf"); 

Tôi đã thay đổi chữ ký.

My Scala lớp trông như thế này,

object spark { 
implicit class RecordServiceContext(ctx: String) { 
def recordServiceTextFile(path: String) : String = { 
"test" 
} 
} 
} 

lớp java của tôi trông như thế này,

public class TestScalaCall { 
public static void main(String args[]){ 
    String s = new spark.RecordServiceContext("safa").recordServiceTextFile("dsf"); 
} 
} 

Sửa ---

Vì vậy, một cái nhìn nhanh chóng của sự thay đổi Scala yêu cầu chương trình chúng tôi this.

Họ đang thực sự làm việc để tạo lớp học được xác định theo cách package object hoạt động giống như cách xác định nó trong một số package thông thường. Nhưng đó là mục tiêu cho việc chưa được phát hành 2.12.

Vì vậy, đề xuất mà chúng đang đưa ra là chỉ giữ các lớp/đối tượng cần thiết hoàn toàn không cần bất kỳ tương tác bên ngoài nào bên trong các đối tượng gói. Nếu không, hãy giữ chúng dưới các gói thông thường. Vì vậy, hiện tại bạn không cần sử dụng cấu trúc package object.

Ngoài ra, một điểm đáng cân nhắc "Liệu nó thực sự làm cho tinh thần để xác định cái gì mà có thể truy cập vào bên ngoài bên trong một đối tượng gói?"

+0

lớp ngầm của bạn thiếu 'gói' trước' đối tượng spark', đó là vấn đề chính tôi đang gặp phải ... – Shankar

+0

tôi đã thêm phần giải thích vào câu trả lời. Đó là điều mà nhóm scala đang làm việc. –

1

Một package object spark được biên dịch để một lớp package trong gói spark. Lớp ngầm RecordServiceContext sẽ được biên dịch thành phương thức tĩnh RecordServiceContext (đó là lỗi ngầm định của scala) trong package và một lớp package$RecordServiceContext.

Vì vậy, các mã sau đây nên làm điều đó:

import com.cloudera.recordservice.spark.*; 

//some code 

RDD<String> rdd = package.RecordServiceContext(myContext).recordServiceTextFile(pathToFile); 

//some code 

Nhưng package có lẽ là một từ khóa dành riêng, và Java không có cách nào thoát họ như xa như tôi biết. Vì vậy, bạn sẽ phải thực hiện một số phản ánh để gọi phương thức RecordServiceContext.

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