Java tương đương với LINQ là gì?
Java tương đương với LINQ là gì?
Câu trả lời:
Không có gì giống như LINQ cho Java.
...
Biên tập
Bây giờ với Java 8, chúng tôi được giới thiệu về API Stream , đây là một loại tương tự khi xử lý các bộ sưu tập, nhưng nó không hoàn toàn giống với Linq.
Nếu đó là ORM mà bạn đang tìm kiếm, như Entity Framework, thì bạn có thể thử Hibernate
:-)
Có một giải pháp thay thế, Coollection .
Sự mát mẻ đã không giả vờ là lambda mới, tuy nhiên chúng tôi được bao quanh bởi các dự án Java cũ mà lib này sẽ giúp. Thật đơn giản để sử dụng và mở rộng, chỉ bao gồm các hành động lặp được sử dụng nhiều nhất trên các bộ sưu tập, như thế:
from(people).where("name", eq("Arthur")).first();
from(people).where("age", lessThan(20)).all();
from(people).where("name", not(contains("Francine"))).all();
Lambdas hiện có sẵn trong Java 8 dưới dạng JSR-335 - Biểu thức Lambda cho Ngôn ngữ lập trình JavaTM
CẬP NHẬT : JDK8 hiện đã được phát hành có chứa dự án lambda. Thật đáng để lấy một bản sao Java 8 đang hoạt động hiện vẫn còn MEAP.
Hãy đọc các bài viết của Brian Goetz liên quan đến lambdas để hiểu rõ về cách thức lambdas được triển khai trong JDK8 trong khi cũng có được sự hiểu biết về các luồng, lặp lại nội bộ, ngắn mạch và các tham chiếu của nhà xây dựng .. Ngoài ra, hãy xem các ví dụ về JSR ở trên để có thêm các ví dụ .
Tôi đã viết blog về một số ưu điểm của việc sử dụng lambdas trong JDK8 có tên là Sức mạnh của Mũi tên , NetBeans 8 cũng hỗ trợ rất nhiều cho việc chuyển đổi các cấu trúc sang JDK8 mà tôi cũng đã viết về Chuyển đổi sang JDK 8 bằng NetBeans .
Bạn có thể chọn các mục trong bộ sưu tập (và nhiều hơn nữa) theo cách dễ đọc hơn bằng cách sử dụng thư viện lambdaj
https://code.google.com.vn/archive/p/lambdaj/
Nó có một số lợi thế so với thư viện Quaere vì nó không sử dụng bất kỳ chuỗi ma thuật nào, nó hoàn toàn an toàn và theo ý kiến của tôi, nó cung cấp DSL dễ đọc hơn.
Bạn sẽ không tìm thấy tương đương với LINQ trừ khi bạn sử dụng javacc để tạo tương đương của riêng bạn.
Cho đến ngày đó khi ai đó tìm thấy một cách khả thi để làm như vậy, có một số lựa chọn thay thế tốt, chẳng hạn như
LINQ to Object - JAVA 8 đã thêm API Stream bổ sung hỗ trợ cho các hoạt động kiểu chức năng trên các luồng giá trị:
Giải thích về Java 8: Áp dụng Lambdas vào Bộ sưu tập Java
LINQ sang SQL / NHibernate / v.v. (truy vấn cơ sở dữ liệu) - Một tùy chọn sẽ là sử dụng JINQ, cũng sử dụng các tính năng JAVA 8 mới và được phát hành vào ngày 26 tháng 2 năm 2014 trên Github: https://github.com/my2iu/Jinq
Jinq cung cấp cho các nhà phát triển một cách dễ dàng và tự nhiên để viết các truy vấn cơ sở dữ liệu trong Java. Bạn có thể coi dữ liệu cơ sở dữ liệu như các đối tượng Java bình thường được lưu trữ trong các bộ sưu tập. Bạn có thể lặp lại chúng và lọc chúng bằng các lệnh Java thông thường và tất cả mã của bạn sẽ được tự động dịch thành các truy vấn cơ sở dữ liệu được tối ưu hóa. Cuối cùng, các truy vấn kiểu LINQ có sẵn cho Java!
Trang web của dự án JINQ: http://www.jinq.org/
Có một dự án gọi là quaere .
Đó là một khung công tác Java có thêm khả năng truy vấn các bộ sưu tập.
Lưu ý: Theo tác giả, dự án không được duy trì nữa.
from x in xs select x
và tìm ra câu trả lời (không).
Có nhiều tương đương LINQ cho Java, xem tại đây để so sánh.
Đối với khung kiểu kiểu Quaere / LINQ an toàn, hãy xem xét sử dụng Querydsl . Querydsl hỗ trợ Bộ sưu tập JPA / Hibernate, JDO, SQL và Java.
Tôi là người duy trì Querydsl, vì vậy câu trả lời này là sai lệch.
Như vào năm 2014, cuối cùng tôi có thể nói rằng LINQ cuối cùng đã có trong java 8. Vì vậy, không cần phải tìm một sự thay thế nào của LINQ nữa.
Bây giờ Java 8 hỗ trợ lambdas, có thể tạo API Java gần giống với LINQ.
Jinq là một trong những thư viện kiểu LINQ mới cho Java.
Tôi là nhà phát triển của thư viện này. Nó dựa trên năm năm nghiên cứu về việc sử dụng phân tích mã byte để dịch Java sang các truy vấn cơ sở dữ liệu. Tương tự như cách D-LINQ của C # là một lớp truy vấn nằm trên Entity Framework, Jinq có thể hoạt động như một lớp truy vấn nằm trên JPA hoặc jOOQ. Nó có hỗ trợ cho tập hợp, nhóm và truy vấn con. Ngay cả Erik Meijer (người tạo ra LINQ) cũng đã thừa nhận Jinq .
Xem SBQL4J . Đó là ngôn ngữ truy vấn mạnh an toàn loại được tích hợp với Java. Cho phép viết các truy vấn lồng nhau phức tạp và nhiều lần. Có rất nhiều toán tử, các phương thức Java có thể được gọi bên trong các truy vấn để làm các hàm tạo. Các truy vấn được dịch sang mã Java thuần túy (không có phản ánh khi chạy) nên việc thực thi rất nhanh.
EDIT: Chà, cho đến nay SBQL4J là phần mở rộng DUY NHẤT cho ngôn ngữ Java mang lại khả năng truy vấn tương tự như LINQ. Có một số dự án thú vị như Quaere và JaQue nhưng chúng chỉ là API, không phải là phần mở rộng cú pháp / ngữ nghĩa với độ an toàn kiểu mạnh trong thời gian biên dịch.
Triển khai Java LINQ to SQL . Cung cấp tích hợp ngôn ngữ đầy đủ và bộ tính năng lớn hơn so với .NET LINQ.
Tôi đã thử thư viện ổi từ google. Nó có một FluentIterable
cái mà tôi nghĩ là gần với LINQ. Cũng xem FunctionalExplained .
List<String> parts = new ArrayList<String>(); // add parts to the collection.
FluentIterable<Integer> partsStartingA =
FluentIterable.from(parts).filter(new Predicate<String>() {
@Override
public boolean apply(final String input) {
return input.startsWith("a");
}
}).transform(new Function<String, Integer>() {
@Override
public Integer apply(final String input) {
return input.length();
}
});
Có vẻ là một thư viện rộng lớn cho Java. Chắc chắn không ngắn gọn như LINQ nhưng có vẻ thú vị.
https://code.google.com.vn/p/joquery/
Hỗ trợ các khả năng khác nhau,
Cho bộ sưu tập,
Collection<Dto> testList = new ArrayList<>();
loại,
class Dto
{
private int id;
private String text;
public int getId()
{
return id;
}
public int getText()
{
return text;
}
}
Bộ lọc
Java 7
Filter<Dto> query = CQ.<Dto>filter(testList)
.where()
.property("id").eq().value(1);
Collection<Dto> filtered = query.list();
Java 8
Filter<Dto> query = CQ.<Dto>filter(testList)
.where()
.property(Dto::getId)
.eq().value(1);
Collection<Dto> filtered = query.list();
Cũng thế,
Filter<Dto> query = CQ.<Dto>filter()
.from(testList)
.where()
.property(Dto::getId).between().value(1).value(2)
.and()
.property(Dto::grtText).in().value(new string[]{"a","b"});
Sắp xếp (cũng có sẵn cho Java 7)
Filter<Dto> query = CQ.<Dto>filter(testList)
.orderBy()
.property(Dto::getId)
.property(Dto::getName)
Collection<Dto> sorted = query.list();
Nhóm (cũng có sẵn cho Java 7)
GroupQuery<Integer,Dto> query = CQ.<Dto,Dto>query(testList)
.group()
.groupBy(Dto::getId)
Collection<Grouping<Integer,Dto>> grouped = query.list();
Tham gia (cũng có sẵn cho Java 7)
Được,
class LeftDto
{
private int id;
private String text;
public int getId()
{
return id;
}
public int getText()
{
return text;
}
}
class RightDto
{
private int id;
private int leftId;
private String text;
public int getId()
{
return id;
}
public int getLeftId()
{
return leftId;
}
public int getText()
{
return text;
}
}
class JoinedDto
{
private int leftId;
private int rightId;
private String text;
public JoinedDto(int leftId,int rightId,String text)
{
this.leftId = leftId;
this.rightId = rightId;
this.text = text;
}
public int getLeftId()
{
return leftId;
}
public int getRightId()
{
return rightId;
}
public int getText()
{
return text;
}
}
Collection<LeftDto> leftList = new ArrayList<>();
Collection<RightDto> rightList = new ArrayList<>();
Có thể tham gia như,
Collection<JoinedDto> results = CQ.<LeftDto, LeftDto>query().from(leftList)
.<RightDto, JoinedDto>innerJoin(CQ.<RightDto, RightDto>query().from(rightList))
.on(LeftFyo::getId, RightDto::getLeftId)
.transformDirect(selection -> new JoinedDto(selection.getLeft().getText()
, selection.getLeft().getId()
, selection.getRight().getId())
)
.list();
Biểu thức
Filter<Dto> query = CQ.<Dto>filter()
.from(testList)
.where()
.exec(s -> s.getId() + 1).eq().value(2);
Bạn có thể dùng thử bộ sưu tập thư viện của tôi . Nó cho phép chạy LINQ như các truy vấn trên các bộ sưu tập các đối tượng. Bạn phải vượt qua vị ngữ, giống như trong LINQ. Nếu bạn đang sử dụng java6 / 7 thì bạn phải sử dụng cú pháp cũ với Giao diện:
List<String> names = Queryable.from(people)
.filter(new Predicate<Person>() {
public boolean filter(Person p) {
return p.age>20;
}
})
.map (new Converter<Person,String>() {
public Integer convert(Person p) {
return p.name;
}
})
.toList();
Bạn cũng có thể sử dụng nó trong Java8 hoặc trong java cũ với RetroLambda và đó là plugin gradle , sau đó bạn sẽ có cú pháp ưa thích mới:
List<String> names = Queryable.from(people)
.filter(p->p.age>20)
.map (p->p.name)
.toList();
Nếu bạn cần chạy các truy vấn DB, hơn bạn có thể tìm kiếm trên JINQ, như đã đề cập ở trên, nhưng nó không thể được cổng lại bởi RetroLambda, doe sử dụng lambdas nối tiếp.
Chỉ cần thêm một lựa chọn khác: Java 6 có một giải pháp cho các truy vấn cơ sở dữ liệu an toàn kiểu bằng cách sử dụng gói javax.persistence.criteria .
Mặc dù tôi phải nói rằng đây không thực sự là LINQ, bởi vì với LINQ bạn có thể truy vấn bất kỳ IEnumerable nào.
Có một thư viện rất tốt mà bạn có thể sử dụng cho việc này.
Nằm ở đây: https://github.com/nicholas22/jpropel-light
Lambdas sẽ không có sẵn cho đến Java 8, vì vậy sử dụng nó hơi khác một chút và không cảm thấy tự nhiên.
Nghe có vẻ như Linq mà mọi người đang nói ở đây chỉ là LinqToObjects. Mà tôi tin rằng chỉ cung cấp chức năng đã có thể hoàn thành ngày hôm nay trong Java, nhưng với cú pháp thực sự xấu xí.
Điều tôi thấy là sức mạnh thực sự của Linq trong .Net là các biểu thức lambda có thể được sử dụng trong ngữ cảnh yêu cầu Đại biểu hoặc Biểu thức và sau đó sẽ được biên dịch thành dạng thích hợp. Đây là những gì cho phép những thứ như LinqToSql (hoặc bất cứ thứ gì khác ngoài LinqToObjects) hoạt động và cho phép chúng có một cú pháp giống hệt với LinqToObjects.
Có vẻ như tất cả các dự án được đề cập ở trên chỉ cung cấp các khả năng của LinqToObjects. Điều này làm cho tôi biết rằng chức năng kiểu LinqToSql không phải là nền tảng cho Java.
Đối với các bộ sưu tập chức năng cơ bản, Java 8 được tích hợp sẵn, hầu hết các ngôn ngữ JVM không phải Java chính đều được tích hợp sẵn (Scala, Clojure, v.v.) và bạn có thể thêm tiện ích cho các phiên bản Java trước đó.
Để truy cập tích hợp ngôn ngữ đầy đủ vào cơ sở dữ liệu SQL, Scala (chạy trên JVM) có Slick
Đối với LINQ (LINQ to Object), Java 8 sẽ có một cái gì đó tương đương, xem Project Lambda .
Nó có các phần mở rộng LINQ to Object như Entsable . Nhưng đối với những thứ LINQ phức tạp hơn như Expression và ExpressionTree (những thứ này cần cho LINQ to SQL và các nhà cung cấp LINQ khác nếu họ muốn cung cấp một cái gì đó được tối ưu hóa và thực tế), không có gì tương đương nhưng có lẽ chúng ta sẽ thấy điều đó trong tương lai :)
Nhưng tôi không nghĩ sẽ có bất cứ điều gì như truy vấn khai báo trên Java trong tương lai.
Không có tính năng như vậy trong java. Bằng cách sử dụng API khác, bạn sẽ có được tính năng này. Giống như giả sử chúng ta có một đối tượng động vật chứa tên và id. Chúng tôi có danh sách các đối tượng có đối tượng động vật. Bây giờ nếu chúng ta muốn lấy tất cả tên động vật có chứa 'o' từ danh sách đối tượng. chúng ta có thể viết truy vấn sau
from(animals).where("getName", contains("o")).all();
Câu lệnh truy vấn trên sẽ liệt kê các động vật chứa bảng chữ cái 'o' trong tên của chúng. Thông tin chi tiết xin vui lòng đi qua blog sau. http://javaworld Worldwide.blogspot.in/2012/09/linq-in-java.html
Kiểm tra nhỏ-q . (Lưu ý rằng bạn hiện không thể tải xuống.)
Dưới đây là một ví dụ điều chỉnh liên kết trên:
Đầu tiên chúng ta cần một bộ sưu tập một số dữ liệu, giả sử một tập hợp các chuỗi
String[] strings = { "bla", "mla", "bura", "bala", "mura", "buma" };
Bây giờ chúng tôi muốn chỉ chọn các chuỗi bắt đầu bằng "b":
Query<String> stringsStartingWithB = new Query<String>(strings).where(
new Query.Func<String, Boolean>(){
public Boolean run(String in) {
return in.startsWith("b");
}
}
);
Không có dữ liệu thực tế được di chuyển sao chép hoặc bất cứ điều gì như vậy, nó sẽ được xử lý ngay khi bạn bắt đầu lặp lại:
for(String string : stringsStartingWithB ) {
System.out.println(string);
}
JaQu là LINQ tương đương với Java. Mặc dù nó được phát triển cho cơ sở dữ liệu H2, nhưng nó sẽ hoạt động cho bất kỳ cơ sở dữ liệu nào vì nó sử dụng JDBC.
Có thể không phải là câu trả lời mà bạn hy vọng, nhưng nếu một phần nào đó trong mã của bạn cần nhiều công sức cho các bộ sưu tập (tìm kiếm, sắp xếp, lọc, biến đổi, phân tích), bạn có thể cân nhắc để viết một số lớp trong Clojure hoặc Scala .
Do tính chất chức năng của chúng, làm việc với các bộ sưu tập là những gì chúng tốt nhất. Tôi không có nhiều kinh nghiệm với Scala, nhưng với Clojure, bạn có thể tìm thấy một Linq mạnh hơn trong tầm tay của bạn và sau khi được biên dịch, các lớp bạn sản xuất sẽ tích hợp liền mạch với phần còn lại của cơ sở mã.
Một người dùng ẩn danh đã đề cập đến một người khác, Dites :
Dites là một thư viện lớp cung cấp các khả năng truy vấn trên các bộ sưu tập thông qua các phương thức có thể tạo chuỗi và giao diện ẩn danh như Linq trong .NET. Không giống như hầu hết các thư viện bộ sưu tập khác đang sử dụng các phương thức tĩnh cần lặp lại toàn bộ bộ sưu tập, Diting cung cấp một chuỗi hàm vô số lớp chứa các phương thức có thể xâu chuỗi để thực hiện truy vấn trên bộ sưu tập hoặc mảng.
Các phương thức được hỗ trợ: bất kỳ, cast, liên hệ, chứa, đếm, phân biệt, phần tửA, ngoại trừ, đầu tiên, FirstOrDefault, groupBy, interet, tham gia, cuối cùng, lastOrDefault, ofType, orderBy, orderByDesceinating, Reverse, select, selectMany, single, single , SkipWhile, Take, TakeWhile, toArray, toArrayList, union, where
Scala. Bây giờ tôi sao đọc nó, và thấy nó giống như linq nhưng đơn giản hơn và khó đọc hơn. nhưng scala có thể chạy ở linux, đúng không? Csharp cần mono.
Có ngôn ngữ lập trình Pizza (một phần mở rộng Java) và bạn nên xem qua nó. - Nó sử dụng khái niệm "giao diện lưu loát" để truy vấn dữ liệu theo cách khai báo và về nguyên tắc giống với biểu thức truy vấn LINQ w / o (http://en.wikipedia.org/wiki/Pizza_programming_lingu). Nhưng than ôi, nó không được theo đuổi, nhưng nó sẽ là một cách để có được thứ gì đó tương tự như LINQ vào Java.
Không có tương đương với LINQ cho Java. Nhưng có một số API bên ngoài trông giống như LINQ, chẳng hạn như https://github.com/nicholas22/jpropel-light , https://code.google.com.vn/p/jaque/
bạn có thể thử thư viện này: https://code.google.com.vn/p/qood/
Dưới đây là một số lý do để sử dụng nó: