Java tốt nhất tương đương với Linq là gì? [đóng cửa]


17

Có thư viện nào trong Java gần cung cấp chức năng của Linq không?


1
Tôi đoán bạn có nghĩa là "cú pháp của LINQ" chứ không phải là "chức năng của LINQ". Có nhiều thư viện cung cấp cùng chức năng :-)
mikera

Tương đương với Java rất có thể là Groovy . Tuy nhiên, với chi phí mất an toàn loại
gnat

Câu trả lời:


20

Để có được cú pháp truy vấn LINQ đầy đủ, bạn sẽ cần một bản cập nhật cho đặc tả ngôn ngữ và trình biên dịch hỗ trợ các từ khóa và cấu trúc cú pháp mới. Điều này vượt xa hầu hết các độc giả ở đây.

Để có được cú pháp chuỗi phương thức giống như Linq trong Java trông và hoạt động giống như những gì trong C #, bạn cần hai điều mà Java không hỗ trợ; các phương thức mở rộng (các phương thức tĩnh có thể được áp dụng cho một thể hiện như thể nó là một phương thức thể hiện) và các biểu thức lambda (các đại biểu ẩn danh). Tuy nhiên, hai cái đó có thể bị giả mạo với các cấu trúc Java hiện có, nếu bạn sẵn sàng chịu thêm một chút chi tiết mã hóa. Một điều tôi thấy đặc biệt tuyệt vời về Java là khả năng tạo các triển khai giao diện ẩn danh; áp dụng cho một giao diện với một chức năng thuần túy, về cơ bản cho phép các đại biểu ẩn danh đơn giản, miễn là bạn có giao diện cho mỗi chữ ký phương thức bạn sẽ cần.

Vì vậy, phía IEnumerable (Iterable for the Javahead) của Linq, như một chuỗi phương thức, có thể xấp xỉ bằng Java; về cơ bản bạn sẽ triển khai nó như một giao diện lưu loát điều khiển một đơn nguyên. Bạn sẽ cần một lớp như một LinqIterable, thực hiện Iterable, rằng:

  • có thể chuyển đổi bất kỳ đầu vào Iterable nào thành một thể hiện LinqIterable
  • có các phương thức để xử lý danh sách cơ bản, chẳng hạn như lọc, nhóm, ghép, giao, đặt hàng, v.v. chấp nhận giao diện chức năng đơn và tạo LinqIterables mới, cho phép xâu chuỗi các phương thức này, hy vọng theo kiểu "lười biếng".
  • có các phương thức để chuyển đổi LinqIterable trở lại thành các đối tượng "cụ thể" như ToList, ToArray, ToMap, v.v.

Vì vậy, bạn có thể có thể định nghĩa một thư viện "thông thạo" sẽ cho phép một câu lệnh như:

Map<String, Integer> results = Linq.FromIterable(sourceList)
                           .Where(new Predicate{public bool Op(SomeStruct in){return in.SomeString == "criteria";}})
                           .OrderBy(new Func{public String Op(SomeStruct in){return in.SomeOtherString;}})
                           .Select(new Func{public SomeOtherStruct Op(SomeStruct in){return new SomeOtherStruct(in.SomeOtherString, in.SomeInt);}})
                           .ToMap(new Func{public String Op(SomeOtherStruct in){return in.StringField;}},
                                  new Func{public Integer Op(SomeOtherStruct in){return in.IntField;}});

Tạo thư viện thực tế là một bài tập vượt xa phạm vi của câu trả lời trên Internet Q & A. Tôi chỉ nói rằng nó có thể, không dễ dàng.

Cây biểu hiện không phải là khoa học tên lửa, nhưng nó sẽ là một dự án quan trọng để thực hiện những gì .NET có trong lĩnh vực này; bạn không chỉ cần khả năng xây dựng một cây biểu thức, bạn còn cần có khả năng "biên dịch" cây này một cách nhanh chóng bằng cách sử dụng mã byte phát ra; Tôi không biết phản xạ của Java có mạnh đến thế không.


2
Cả hai phương thức mở rộng và các biểu thức lambda đều có trong Java 8. Có lẽ LINQ đang trên đường?
lxs

4
Chà, nếu bạn có các phương thức mở rộng và lambdas, bạn có khía cạnh "Có thể đếm được" của Linq của .NET mà không cần nỗ lực lớn. Như tôi đã nói, nó vẫn sẽ yêu cầu thay đổi thông số Java để cho phép các từ khóa tạo truy vấn Linq, nhưng thành thật mà nói trong việc sử dụng Linq hàng ngày tôi không tìm thấy quá nhiều truy vấn không dễ dàng như vậy được biểu thị dưới dạng chuỗi phương thức và trình biên dịch chuyển đổi cú pháp Linq thành chuỗi phương thức (trình cắm VS tồn tại có thể chuyển đổi 1: 1 giữa hầu hết các truy vấn và chuỗi). Bước đệm thực sự tiếp theo sẽ là cây biểu thức (Truy vấn Linq).
KeithS

8

Xem:


1
bạn có muốn mở rộng một chút về những gì mỗi tài nguyên này có và tại sao bạn lại đề xuất những tài nguyên này khi trả lời câu hỏi không? "Câu trả lời chỉ liên kết" không được chào đón tại Stack Exchange
gnat

Hmm, tôi đoán đó là một trường hợp mà Q này đã được trả lời - nên được sửa đổi như một bản sao?
Martijn Verburg

1
@MartijnVerburg - chúng tôi không thể đánh dấu các câu hỏi là trùng lặp trên các trang web. Câu trả lời thực sự cần phải có khả năng đứng một mình.
ChrisF

Đã chỉnh sửa, hy vọng bây giờ nó hữu ích hơn một chút.
Martijn Verburg

5

Không. Linq yêu cầu rất nhiều tính năng langage mà Java chỉ cần có


4
Java không có khái quát.
Jonas

6
@Jonas: Điều đó đúng, nhưng liệu họ có thực sự đủ mạnh để hỗ trợ LINQ hay không lại là một vấn đề khác.
DeadMG

2
@DeadMG vẫn vậy, Java không có khái quát.
Mahmoud Hossam

Đã chỉnh sửa để xóa tham chiếu đến thuốc generic
Tom Squires

3

Sử dụng Scala , vì những lý do được giải thích ở đây :

sử dụng cổng .NET của Scala. Nó cung cấp cho bạn toàn quyền truy cập vào mọi thứ trong .NET, rõ ràng bao gồm LINQ.

Nếu bạn không thể, bạn có thể thử sử dụng lib như functionjava hoặc lambdaj , nhưng bạn sẽ không thực sự đến gần với LINQ.


1
Scala không bao gồm bất cứ thứ gì như Linq mà không có thư viện.
Jonas

1
@Jaas: Vậy sao? Java không bao gồm bất cứ thứ gì như Linq với các thư viện.
back2dos

@ back2dos: Vâng, đó là lý do tại sao bạn phải trả lời với một thư viện.
Jonas

1
@Jonas: Thư viện tiêu chuẩn của Scala giống như LINQ. Hoặc ngược lại: LINQ chỉ là một tập hợp các thành ngữ lập trình chức năng cho C #. Thêm về điều đó ở đây .
back2dos

@ back2dos: Cảm ơn vì liên kết tuyệt vời, tôi đã tự do đưa nó vào.
Landei

2

Tôi sẽ thêm ổi vào danh sách các thư viện có thể giúp bạn đạt được một số điều mà LINQ làm.

Nhưng như những người khác đã chỉ ra, không có Java tương đương.


bạn có phiền giải thích thêm về những gì nó làm không và tại sao bạn lại đề nghị nó như trả lời câu hỏi được hỏi? "Câu trả lời chỉ liên kết" không được chào đón tại Stack Exchange
gnat

2

Bạn có thể sử dụng Korma , DSL cho các truy vấn SQL được viết bằng Clojure.

Cú pháp khá gọn gàng:

(select user
  (with address)
  (fields :firstName :lastName :address.state)
  (where {:email "korma@sqlkorma.com"}))

Bạn có thể gọi điều này khá dễ dàng từ Java bằng cách nhập các thư viện Clojure có liên quan và chỉ cần sử dụng interj Clojure / Java bình thường.


Vì vậy, điều này sẽ mô phỏng Linq qua SQL, không phải LINQ trên các đối tượng, phải không?
Công việc

@Job: vâng, nó được thiết kế cho SQL. Mặc dù tôi không thấy bất kỳ lý do nào mà nó không thể được mở rộng / điều chỉnh cho các đối tượng.
mikera

2

Không có một tính năng gốc trong java bắt chước linq. Tuy nhiên, có một số API cung cấp cùng chức năng.

Ví dụ, bài đăng trên blog này có một bình tùy chỉnh để sao chép linq.
http://javaworld Worldwide.blogspot.in/2012/09/linq-in-java.html

Và đây là một ví dụ sử dụng API từ bài đăng:

Giả sử chúng ta có một đối tượng Động vật chứa tên và ID được thể hiện bằng một danh sách animals. Nếu chúng tôi muốn lấy tất cả các tên Động vật có chứa 'o' từ danh sách animals, chúng tôi có thể viết truy vấn sau

from(animals).where("getName", contains("o")).all();

Có hai API khác được tham chiếu trong bài đăng trên blog: lambdaJjLinq


1
Tôi sợ rằng việc mất cả kiểm tra kiểu tĩnh và kiểm tra sự tồn tại của một thành viên trong lớp là một mức giá hơi cao để gọi cho một cuộc gọi như thế nào where("getName", ...).
9000
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.